【问题标题】:R subset rows for all occurrences of first variable in column列中所有出现的第一个变量的 R 子集行
【发布时间】:2016-08-25 01:10:39
【问题描述】:

我想基于两列 ColA 和 ColB(下图)创建一个大型数据框的子集。对于 ColA 中的每个变量(例如 A、B、C ...),我想提取与 ColB 中第一个变量的每次出现相对应的行。因此DF1:

ColA  ColB  ColC
A     Red     7thing
A     Red     OneBot
A     Blue    BotOne
B     Green   Thing7
B     Green   Twosies
B     Green   Square
B     Yellow  Circle
B     Yellow  Polygon
B     Purple  Triangle
B     White   Octagon
C     Orange  Cube
C     Black   Line

将成为 DF2:

ColA  ColB  ColC
A     Red     7thing
A     Red     OneBot
B     Green   Thing7
B     Green   Twosies
B     Green   Square
C     Orange  Cube

我不关心 ColC 中的重复,并且 ColB 中变量的出现次数没有规律。我发现相关的子集策略专注于提取独特的案例,但我既没有遇到也无法设计一种方法来允许选择第一个变量类型的所有出现,并且希望能提供一些帮助。

我试过了

DF2 <- DF1[match(unique(DF1$ColB), DF1$ColB),]

...以及当变量内容已知时以变量为目标的子集(例如Subset first n occurrences of certain value in dataframe in R),这些看似不合适。

【问题讨论】:

  • 你试过什么代码? SO 是编码资源而不是编码服务
  • 我已经编辑了我的帖子以包含一些代码,如果有帮助可以添加更多,但问题不是其他适当代码中的错误,这就是我没有包含它的原因。抱歉,如果我的问题是期待服务,但事实并非如此,SO 指南似乎建议包含代码并不适合每个问题,这是我用作指南的内容。

标签: r dataframe subset


【解决方案1】:

ave 在基础 R 中的强大功能,将所有 ColB 案例与每组中的第一个 ColB 进行比较:

dat[with(dat, ColB == ave(ColB, ColA, FUN=function(x) head(x,1) )),]

#   ColA   ColB    ColC
#1     A    Red  7thing
#2     A    Red  OneBot
#4     B  Green  Thing7
#5     B  Green Twosies
#6     B  Green  Square
#11    C Orange    Cube

使用您的原始逻辑,您也可以 merge 仅返回 ColA/ColB 的非重复记录:

merge(dat, dat[c("ColA","ColB")][!duplicated(dat$ColA),])

【讨论】:

  • 太好了,也感谢您指出合并策略。
【解决方案2】:

aggregate 的另一种方法

df[df$ColB %in% unlist(aggregate(ColB~ColA, df, function(x) head(x, 1))[2]), ]

#    ColA   ColB    ColC
#1     A    Red  7thing
#2     A    Red  OneBot
#4     B  Green  Thing7
#5     B  Green Twosies
#6     B  Green  Square
#11    C Orange    Cube

【讨论】:

    【解决方案3】:

    由于它是一个大数据集,使用 data.table 的方法是

    library(data.table)
    setDT(df1)[df1[, .I[ColB==ColB[1L]], ColA]$V1]
    #   ColA   ColB    ColC
    #1:    A    Red  7thing
    #2:    A    Red  OneBot
    #3:    B  Green  Thing7
    #4:    B  Green Twosies
    #5:    B  Green  Square
    #6:    C Orange    Cube
    

    .SD

    setDT(df1)[, .SD[ColB==ColB[1L]], ColA]
    

    【讨论】:

      【解决方案4】:

      你可以使用dplyr来完成你想要的:

      library(dplyr)
      df2 <- df1 %>% group_by(ColA) %>% filter(ColB == first(ColB))
      

      首先group_byColA,然后filter 只保留ColB 等于firstfirst 值的行。使用您的数据的结果是:

      print(df2)
      ##Source: local data frame [6 x 3]
      ##Groups: ColA [3]
      ##
      ##    ColA   ColB    ColC
      ##  <fctr> <fctr>  <fctr>
      ##1      A    Red  7thing
      ##2      A    Red  OneBot
      ##3      B  Green  Thing7
      ##4      B  Green Twosies
      ##5      B  Green  Square
      ##6      C Orange    Cube
      

      【讨论】:

      • 不知道你为什么被否决?!这工作得很好。
      • @thelatemail:感谢您的支持!只要 OP 得到他/她想要的东西,我就很好。
      • 感谢 aichao 和 thelatemail,这个 group_by 方法简单实用!
      猜你喜欢
      • 1970-01-01
      • 2019-10-11
      • 1970-01-01
      • 1970-01-01
      • 2020-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多