2013-08-21 37 views
3

对不明确的标题感到抱歉。下面是关注的data.table:数据准备问题

dt <- data.table(K=c("A","A","A","B","B","B"),Y=c("2010","2010","2011","2011","2011","2010"),Q1=c(2,3,4,1,3,4),Q2=c(3,3,3,1,1,1)) 
dt 
    K Y Q1 Q2 
1: A 2010 2 3 
2: A 2010 3 3 
3: A 2011 4 3 
4: B 2011 1 1 
5: B 2011 3 1 
6: B 2010 4 1 

假设K的值是人,所以我们在这里有两个。一年中的季度存储在Q1和Q2中。 Q2是一种参考四分之一变量,其值始终与2011年相关)。现在我想选择dt中的那些行,对于K中的每个Person,Q1都位于Q2值之前4个季度的区间内。

一个例子:
人A在Q2值3,所以值2(2011),1(2011),4(2010),和3(2010)应该被拾取。考虑到这个数据集,这只是第2行。第3行中的值Q1 = 4太大,第1行中的值Q1 = 2太小。对于第二个人“B”,只会选择第6行。也不行4,因为这是同一个季度在第二季度(我想只比第二季度的数值那些规模较小,第5行是明显高于第二季度的值大

dt_new 
    K Y Q1 Q2 
1: A 2010 3 3 
2: B 2010 4 1 

综上所述
Q2中的数值4意味着:选取Q1中所有小于4的值,其中Y = 2011,并选取Q1中所有等于或大于4的值(所以只是4),其中Y = 2010。 (2011),2(2011),1(2011),4(2010)。此规则适用于Q2的所有数值,所有这些都应为每个人完成。有很多方法可以解决这个问题,但是因为我是sti我会学习data.table,我想问你一些不错的和优雅的解决方案(希望有)。

感谢

编辑:
几乎找到了解决办法:这给了我一个合乎逻辑的载体。我如何提取数据集中的行?

setkey(dt,K) 
dt[,(Q1<Q2 & Y=="2011")|(Q1>=Q2 & Y=="2010"),by="K"] 
    K V1 
1: A FALSE 
2: A TRUE 
3: A FALSE 
4: B FALSE 
5: B FALSE 
6: B TRUE 

没有这样做:

log <-dt[,(Q1<Q2 & Y=="2011")|(Q1>=Q2 & Y=="2010"),by="K"]$V1 
dt[log] 

回答

4

这是一种香草逐行过滤,所以你并不需要(或不应该)使用分组(by = "K"),只是做:

dt[(Q1 < Q2 & Y == "2011") | (Q1 >= Q2 & Y == "2010"), ] 

或者如果您打算使用4季度以外的范围,则可能更灵活一些:

quarter.diff <- function(Q1, Y1, Q2, Y2) { 
    4L * (as.integer(Y2) - as.integer(Y1)) + 
     (as.integer(Q2) - as.integer(Q1)) 
} 

dt[quarter.diff(Q1, Y, Q2, Y2 = "2011") > 0L & 
    quarter.diff(Q1, Y, Q2, Y2 = "2011") <= 4L, ] 

这不仅仅是更一般的说法,它会读得更好,并使得假设是明确的。

请注意,我小心地将quarter.diff函数中的所有列转换为整数。理想情况下,您的年份和季度数据将以整数形式存储,而不是字符或数字。

最后,如果你担心quarter.diff被称为两次,速度是一个问题,你可以临时存储结果作为@Arun在评论中建议:

dt[{qdiff <- quarter.diff(Q1, Y, Q2, Y2 = "2011") 
    qdiff > 0L & qdiff <= 4L}, ] 
+2

可以减少'季度双呼叫。通过将结果赋值给一个变量,比如'w',然后做:'which(w> 0L&w <= 4L)',你可以这样做:'dt [quarter.diff(Q1,Y, Q2,Y2 =“2011”)]'。 – Arun

+1

小语法注释 - 你不需要'dt [i-expression]中的逗号' – eddi