【问题标题】:R First Row By Group When Condition Is Met满足条件时按组的R第一行
【发布时间】:2020-08-26 22:19:01
【问题描述】:
dataHAVE=data.frame(STUDENT=c(1,1,1,2,2,2,3,3,3),
SCORE=c(0,1,1,5,1,2,1,1,1),
CAT=c(3,10,7,4,5,0,4,5,1),
FOX=c(5,0,10,8,9,1,8,9,0))

dataWANT=data.frame(STUDENT=c(1,2,3),
SCORE=c(1,1,1),
CAT=c(10,5,4),
FOX=c(0,9,8))

我有 'dataHAVE' 并且想要 'dataWANT' 当 'SCORE' 等于 1 时,它为每个 'STUDENT' 占据第一行。我正在寻找一个 data.table 解决方案,因为它是一个大数据。我试试这个,但不知道如何设置'SCORE'的标准

dataWANT[,.SD[1],by = key(STUDENT)]

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    将'data.frame'转换为'data.table'(setDT),按'STUDENT'分组,在i中指定逻辑条件,获取第一行的索引(.I[1]),提取该列 ($V1) 并对行进行子集化

    library(data.table)
    setDT(dataHAVE)[dataHAVE[SCORE == 1, .I[1], STUDENT]$V1]
    

    .I 返回行索引。如果我们没有分组列,它将返回 vector

    setDT(dataHAVE)[SCORE == 1, .I]
    #[1] 1 2 3 4 5 6
    

    当我们提供分组列时,默认情况下,.I 返回一个命名列 V1(我们可以通过更改名称来覆盖它)

    setDT(dataHAVE)[SCORE == 1, .(colindex = .I[1]), STUDENT]
    #    STUDENT colindex
    #1:       1        2
    #2:       2        5
    #3:       3        7
    

    现在,我们有两列,'STUDENT','colindex'。我们对“colindex”特别感兴趣,因此使用标准程序($[[)进行提取,然后将其用作i 中的行索引

    i1 <- setDT(dataHAVE)[SCORE == 1, .(colindex = .I[1]), STUDENT]$colindex
    i1
    #[1] 2 5 7
    

    我们用于子集化

    dataHAVE[i1]
    

    【讨论】:

    • 非常感谢您能帮我理解'.I'和$V1的含义
    • 这太棒了,非常感谢!我的最后一个问题是,如果我不想输出而是保存它,我应该修改什么?我试图摆脱'。在'.I'中,但我想知道我要排除什么以便不打印它而只是修改它?
    • @bvowe 您可以将其分配给新对象out &lt;- setDT(dataHAVE)[dataHAVE[SCORE == 1, .I[1], STUDENT]$V1]
    【解决方案2】:

    这是使用subset + ave 的基本 R 选项

    subset(
      dataHAVE,
      ave(SCORE==1, STUDENT, FUN = function(x) seq_along(x) == min(which(x)))
    )
    

    给了

      STUDENT SCORE CAT FOX
    2       1     1  10   0
    5       2     1   5   9
    7       3     1   4   8
    

    【讨论】:

      【解决方案3】:

      解决方案 1. 有两行简单而全面的解决方案:

      dataWANT <- dataHAVE[dataHAVE$SCORE == 1,]            #Filter score equals to 1
      dataWANT <- dataWANT[!duplicated(dataWANT$STUDENT), ] #Remove duplicated students
      

      解决方案 2。 但是,如果您更喜欢在一行中解决:

      dataWANT <- dataHAVE[!duplicated(paste0(dataHAVE$STUDENT, dataHAVE$SCORE)) & dataHAVE$SCORE ==1, ]
      

      这会创建一个逻辑向量,显示哪些组合不与前面的元素重复,并将其与“SCORE”是否为 1 的测试相结合。

      【讨论】:

      • 这里的方案1简单易懂。我不知道为什么人们更喜欢复杂且可读性较差但不一定更有效的解决方案。
      【解决方案4】:

      您可以使用match 获取第一行,其中SCORE = 1 对应每个STUDENT

      library(data.table)
      
      setDT(dataHAVE)
      dataHAVE[, .SD[match(1, SCORE)], STUDENT]
      
      #   STUDENT SCORE CAT FOX
      #1:       1     1  10   0
      #2:       2     1   5   9
      #3:       3     1   4   8
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-31
        • 1970-01-01
        • 1970-01-01
        • 2015-11-12
        • 2023-02-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多