代码之家  ›  专栏  ›  技术社区  ›  Eric Green

按条件分组的样本值

  •  0
  • Eric Green  · 技术社区  · 4 年前

    我对数据进行了分组,我想创建一个新变量 value 这将取0或1的值。

    1. 每个小组至少需要一次观察 value==1 .
    2. 但在以下情况下,小组的观察次数不能超过2次: 值==1 .
    3. 理想情况下,我可以将其设置为不超过25%的组只进行一次观察 值==1 .
    library(tidyverse)
    set.seed(1)
    
    # sample can break the rules
    tibble(group = c(rep("A", 3),
                     rep("B", 6),
                     rep("C", 4),
                     rep("D", 5))) %>%
      group_by(group) %>%
      mutate(value = sample(c(0, 1), n(), replace = TRUE, prob = c(0.8, 0.2)))
    
    2 回复  |  直到 4 年前
        1
  •  1
  •   jdobres    4 年前

    一个解决方案是创建一个独特的组标签列表,并将其洗牌(这里我通过 nest )。然后,根据组是否位于数据帧的前25%行中,您可以指定a)介于1和2之间的随机数,或b)始终为2。最后,您可以使用分配的编号定义如何对每个组的0和1进行采样,然后取消对结果的测试。

    set.seed(0)
    result <- df %>% 
      nest(data = -group) %>% 
      .[sample(1:nrow(.), nrow(.)), ] %>% # shuffle the group order
      mutate(
        value_count = ifelse(row_number() / n() <= 0.25, sample(1:2, n(), replace = T), 2)
      ) %>% 
      rowwise() %>% 
      mutate(
        count = nrow(data),
        value = list(sample(c(rep(1, value_count), rep(0, count - value_count)), count))
      ) %>% 
      unnest(value) %>% 
      select(-data, -value_count, -count)
    
       group value
       <chr> <dbl>
     1 B         0
     2 B         0
     3 B         0
     4 B         0
     5 B         1
     6 B         0
     7 A         1
     8 A         1
     9 A         0
    10 D         1
    11 D         0
    12 D         1
    13 D         0
    14 D         0
    15 C         1
    16 C         0
    17 C         0
    18 C         1
    
        2
  •  1
  •   mrhellmann    4 年前

    看起来我被打败了,但这里有另一种方法:

    library(tidyverse)
    
    set.seed(1)
    
    # sample can break the rules
    x <- tibble(group = c(rep("A", 3),
                     rep("B", 6),
                     rep("C", 4),
                     rep("D", 5)))
    
    # Make all 'var' =1, then set all but first of each group to 0.
    xx <- x %>% group_by(group) %>%
      mutate(var = row_number()) %>%
      mutate(var = ifelse(var == 1, 1, 0))
    
    
    pct_with_two <- .75 # percentage of groups with two 1's
    samp_size <- floor(length(unique(xx$group)) * pct_with_two) #round down to whole number
    addl_one <- sample(unique(xx$group), size = samp_size, replace = F)
    
    xx %>% 
      mutate(var2 = case_when(
        group %in% addl_one & row_number() == 2 ~ 1, 
        TRUE ~0)) %>% 
      mutate(var = var+var2) %>% 
      select(-var2)
    #> # A tibble: 18 x 2
    #> # Groups:   group [4]
    #>    group   var
    #>    <chr> <dbl>
    #>  1 A         1
    #>  2 A         1
    #>  3 A         0
    #>  4 B         1
    #>  5 B         0
    #>  6 B         0
    #>  7 B         0
    #>  8 B         0
    #>  9 B         0
    #> 10 C         1
    #> 11 C         1
    #> 12 C         0
    #> 13 C         0
    #> 14 D         1
    #> 15 D         1
    #> 16 D         0
    #> 17 D         0
    #> 18 D         0
    

    于2022年3月11日由 reprex package (v0.3.0)