【问题标题】:Select rows in data.table based on in-row calculation根据行内计算选择 data.table 中的行
【发布时间】:2014-04-03 12:30:44
【问题描述】:

数据集是这样的:

library(data.table)
uid <- c("a","a","a","b","b","b","c","c","c")
date <- c(2001,2002,2003)
DT <- data.table(id=uid, year=rep(date,3), value= c(1,3,2,1:6))

第一季度

现在我想找出哪些观察值的“值”列逐年增加 我想要的是这样的: 对于 b 和 c,值一直在增加。

4: b 2001 1 5: b 2002 2 6: b 2003 3 7:c 2001 4 8:c 2002 5 9:c 2003 6

在真实数据中,每个id的记录时间跨度是不同的。

此外,我想计算:对于给定的 id,值增加了多少年。

标识 V1 1:一个 1 2:乙2 3:c 2

如果您对此有一些想法,非常感谢。 由于速度计算要求,我更喜欢 data.table 方法。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    我认为这是你想要的:

    DT[order(year)][, sum(diff(value) > 0), by=id]
    

    产生:

       id V1
    1:  a  1
    2:  b  2
    3:  c  2
    

    这假设您每年最多有一个值。

    【讨论】:

      【解决方案2】:

      对于您的第一个问题,如果它们没有排序,我会在 id, year 上使用 setkey 进行排序(而不是使用 base:::order,因为它非常慢)。还添加了id,以便您也可以按照与问题 2 相同的顺序获得结果。

      setkey(DT, id, year)
      DT[, if (.N == 1L || 
              ( .N > 1 && all(value[2:.N]-value[1:(.N-1)] > 0) )
           ) .SD, 
      by=list(id)]
      
         id year value
      1:  b 2001     1
      2:  b 2002     2
      3:  b 2003     3
      4:  c 2001     4
      5:  c 2002     5
      6:  c 2003     6
      

      第二个问题:

      DT[, if (.N == 1L) 1L else sum(value[2:.N]-value[1:(.N-1)] > 0), by=list(id)]
         id V1
      1:  a  1
      2:  b  2
      3:  c  2
      

      我取第二个到最后一个 (.N) 值,然后用第一个到第 n-1 个显式减去它,因为 diff 作为 S3 泛型将需要时间来调度正确的方法(此处为 diff.default)和直接在j中编写函数会快得多。

      【讨论】:

      • Arun,setkey(DT, year, id)[, sum(diff.default(value) &gt; 0), by=id] 会是速度和易读性/简洁性之间的合理折衷方案吗?
      猜你喜欢
      • 2019-01-15
      • 2017-01-18
      • 1970-01-01
      • 2022-01-24
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多