R语言 从组中随机选择值序列

c86crjj0  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(119)

数据如下:

df <-
  data.frame(group = c(1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4),
             value = LETTERS[1:20])

字符串
我需要用dplyr从每组中随机选择四个值的序列。所选值的顺序应该与数据中的顺序相同,并且它们之间不应该有间隙。
期望的结果可能看起来像这样:

group value
1      1     A
2      1     B
3      1     C
4      1     D
6      2     F
7      2     G
8      2     H
9      2     I
11     3     K
12     3     L
13     3     M
14     3     N
17     4     Q
18     4     R
19     4     S
20     4     T

   group value
1      1     A
2      1     B
3      1     C
4      1     D
5      2     E
6      2     F
7      2     G
8      2     H
10     3     J
11     3     K
12     3     L
13     3     M
17     4     Q
18     4     R
19     4     S
20     4     T


这就是我解决这个问题的地方:

set.seed(23)
df %>% 
  group_by(group) %>% 
  mutate(selected = sample(0:1, size = n(), replace = TRUE)) %>% 
  filter(selected == 1)


然而,我不知道如何在一行中生成正好4个1,在它们之前或之后有0。

bwleehnv

bwleehnv1#

我们可以sample组中的行数(* 减3 *),大小为1,然后加上0:3来选择我们保留的行。

set.seed(42)
df %>%
  group_by(group) %>%
  filter(row_number() %in% c(sample(max(1, n()-3), size=1) + 0:3)) %>%
  ungroup()
# # A tibble: 16 × 2
#    group value
#    <dbl> <chr>
#  1     1 A    
#  2     1 B    
#  3     1 C    
#  4     1 D    
#  5     2 E    
#  6     2 F    
#  7     2 G    
#  8     2 H    
#  9     3 J    
# 10     3 K    
# 11     3 L    
# 12     3 M    
# 13     4 Q    
# 14     4 R    
# 15     4 S    
# 16     4 T

字符串
安全步骤:

  • max(1, n()-3)确保我们不会尝试对负数(或零)行进行采样
  • 如果我们有一个少于4行的组,这仍然有效(选择所有行),因为row_number() %in% ...永远不会尝试索引不存在的行,即使c(sample(.) + 0:3)可能 * 建议 * 比存在的更多的行。
jk9hmnmh

jk9hmnmh2#

您可以尝试使用embed(但不如answer by @r2evans高效)

df %>%
    filter(
        value %in% embed(value, 4)[sample.int(n() - 3, 1), ],
        .by = group
    )

字符串

df %>%
    summarise(
        value = list(embed(value, 4)[sample.int(n() - 3, 1), 4:1]),
        .by = group
    ) %>%
    unnest(value)

相关问题