根据行内计算选择data.table中的行

时间:2014-03-02 16:24:30

标签: r data.table

数据集类似于:

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))

Q1

现在我想找出哪些观察值的“价值”列逐年增加 我想要的是这样的: 对于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,值增加了多少年。

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

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

2 个答案:

答案 0 :(得分:3)

我认为这可以满足您的需求:

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

产生

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

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

答案 1 :(得分:2)

对于您的第一个问题,如果它们没有排序,我会在setkeyid, year进行排序(而不是使用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

我取第2个到最后一个(.N)值并明确地减去1到n-1,因为作为S3泛型的diff需要时间来分派正确的方法(这里,{{1在diff.default中直接编写函数会快得多。