重新采样可变长度的组,使组长度相等(R,dplyr)

时间:2015-03-28 01:53:28

标签: r dplyr

我有一个数据集,其中组之间的行数可以变化。我需要在每个组中随机抽样替换,以便行数等于预定值。

下面我有一个示例DATA和所需的RESULT表。在这个例子中,我需要随机抽样每个组,以便每个SITE有4行。此外,由于SITE$A已有4行,因此不应对其进行重新采样。

请注意RESULT表如何保留STUFF:STUFF3列中的数据顺序。我更喜欢使用dplyr的答案,因为我广泛使用这个包,但我对其他解决方案持开放态度。

  NUMBER = 4

    DATA = data.frame(SITE = c("A","A","A","A","B","B","B","C","C"),  
                      STUFF = c(1, 2, 30, 40, 100, 200, 300, 5000, 6000),
                      STUFF2 = c(2, 4, 60, 80, 200, 400, 600, 10000, 12000),
                      STUFF3 = c(4, 8, 120, 160, 400, 800, 1200, 20000, 24000))



   RESULT = data.frame(SITE = c("B","C","C"), 
                    STUFF = c(200, 5000, 5000),
                    STUFF2 = c(400, 10000, 10000),
                    STUFF3 = c(800, 20000, 20000))

我已尝试过以下代码的各种迭代......但没有成功。提前致谢。

RESULT = group_by(DATA, SITE)%>%
  sample_n(NUMBER - length(.), replace = TRUE)

2 个答案:

答案 0 :(得分:3)

如果我正确理解了这个问题,RESULTDATA的某种补充数据框,例如当它们组合在一起时,它们会为每个组生成4行。

NUMBER <- 4

set.seed(1234)

RESULT2 <- DATA %>%
  group_by(SITE) %>%
  mutate(n = n(),
         sampsize = as.numeric( ifelse(n>=NUMBER,0,NUMBER-n)) ) %>%
  do( sample_n(., size=.$sampsize[1], replace=TRUE ) ) %>%
  select( -n, -sampsize ) %>%
  ungroup()

RESULT2

产生这个:

Source: local data frame [3 x 4]

  SITE STUFF STUFF2 STUFF3
1    B   100    200    400
2    C  6000  12000  24000
3    C  6000  12000  24000

如果需要完整的数据集(将DATARESULT组合成一个具有特定排序要求的数据框),则可以使用以下内容:

NUMBER <- 4

set.seed(1234)

RESULT3 <- DATA %>%
  group_by(SITE) %>%
  mutate(n = n(),
         sampsize = as.numeric( ifelse(n>=NUMBER,0,NUMBER-n)) ) %>%
  do( rbind(.,sample_n(., size=.$sampsize[1], replace=TRUE )) ) %>%
  select( -n, -sampsize ) %>%
  ungroup()

RESULT3

产生这个:

Source: local data frame [12 x 4]

   SITE STUFF STUFF2 STUFF3
1     A     1      2      4
2     A     2      4      8
3     A    30     60    120
4     A    40     80    160
5     B   100    200    400
6     B   200    400    800
7     B   300    600   1200
8     B   100    200    400
9     C  5000  10000  20000
10    C  6000  12000  24000
11    C  6000  12000  24000
12    C  6000  12000  24000

请注意,如果NUMBER小于组RESULT3中的记录数,则会显示未修改的整个组。

答案 1 :(得分:0)

这是@akhmed代码的一个版本,它结合了mutate语句。使用do中的dplyr函数我会变得更好。谢谢。

RESULT4 <- group_by(DATA, SITE) %>%
      mutate(sampsize = NUMBER - n())%>%
      do (sample_n(., size = .$sampsize[1], replace=TRUE )) %>%
      select(-sampsize ) %>%
      ungroup()