在长数据集中随机选择每个ID一个剧集

时间:2017-11-17 11:28:21

标签: r dataframe random grouping

我有一个长格式数据集,其中每个ID有多个剧集,每集有多行。我想随机选择每个ID一个剧集及其所有相关行。

例如:

df <- data.frame(id = c(1,1,1,2,2,2,2), 
    episode = c(1,2,2,1,1,1,2))
df
  id episode
 1  1       1
 2  1       2
 3  1       2
 4  2       1
 5  2       1
 6  2       1
 7  2       2

...我想留下这个数据集:

df2
  id episode
1  1       2
2  1       2
3  2       1
4  2       1
5  2       1

3 个答案:

答案 0 :(得分:1)

这是使用基础R的选项:

1)对原始数据进行采样

dfsampled <- df[sample(seq_len(nrow(df))),]

2)将非重复样本数据与原始数据合并:

merge(dfsampled[!duplicated(dfsampled$id),], df, all.x = TRUE)

#  id episode
#1  1       2
#2  1       2
#3  2       1
#4  2       1
#5  2       1

和dplyr方法:

library(dplyr)
df %>% group_by(id) %>% filter(episode == sample(unique(episode), 1))
# A tibble: 5 x 2
# Groups:   id [2]
     id episode
  <dbl>   <dbl>
1     1       2
2     1       2
3     2       1
4     2       1
5     2       1

答案 1 :(得分:0)

这是一个带有ave和子集的基本R方法。

set.seed(1234)
df[df$episode == ave(df$episode, df$id, FUN=function(x) sample(x, size=1)),]

在这里,avesample应用于每个ID,选择单个剧集并返回一个向量,即每个id的单个剧集的data.frame行数的长度。 data.frame是子集,它将每个id中的剧集与返回的矢量进行比较。

此实例返回

  id episode
1  1       1
4  2       1
5  2       1
6  2       1

data.table中,您可以

library(data.table)
set.seed(1234)
setDT(df)[df[, sample(episode, 1), by=id], on=.(id, "episode"=V1)]

这将返回与上面相同的结果(除了它将是data.table而不是data.frame。

答案 2 :(得分:0)

使用dplyr

set.seed(123)
df%>%group_by(id)%>%
mutate(new=sample(episode,1))%>%
filter(episode!=new)%>%
select(id,episode)

# A tibble: 5 x 2
# Groups:   id [2]
#     id    episode
#    <dbl>   <dbl>
#1     1       2
#2     1       2
#3     2       1
#4     2       1
#5     2       1