【问题标题】:Randomly selecting one episode per ID in long dataset在长数据集中每个 ID 随机选择一集
【发布时间】:2017-11-17 11:28:21
【问题描述】:

我有一个长格式数据集,其中每个 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

【问题讨论】:

  • 据我所知,您的预期输出显示每个 ID 的多个剧集。这是笔误吗?
  • df[df$episode != df$id, ]
  • 这表明对于 ID 1 我只选择了第 2 集,而对于 ID 2 我只选择了第 1 集。这就是我想要获得的。抱歉,如果问题不清楚。

标签: r dataframe random grouping


【解决方案1】:

这是一个使用 base 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

【讨论】:

    【解决方案2】:

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

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

    在这里,avesample 应用于每个 id,选择单个情节并返回一个向量,该向量表示 data.frame 的行数的长度,每个 id 有一个情节。通过将每个 id 中的情节与返回的向量进行比较,data.frame 是子集。

    这个实例返回

      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。

    【讨论】:

      【解决方案3】:

      使用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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-03
        • 2010-09-12
        • 1970-01-01
        • 2018-09-11
        相关资源
        最近更新 更多