说我有以下数据表:
prc = c(2,5,4,6,7,3)
ret = c(0.01,0.03,-0.02,0.01,-0.001,0.04)
cap = c(100,200,300,80,40,900)
comp = c("a","a","a","b","b","c")
dt = data.table(comp, prc, ret, cap)
comp prc ret cap
1: a 2 0.010 100
2: a 5 0.030 200
3: a 4 -0.020 300
4: b 6 0.010 80
5: b 7 -0.001 40
6: c 3 0.040 900
我想基于以下条件进行操作:对于每个公司,在第t行,必须在行(t-2)处有一个prc,在行(t-1)处有一个prc,并且在(t- 2)。因此,我将操作的唯一行是3.
我试过这个:
> dt[, which(is.na(shift(prc,2)) | is.na(shift(ret,1)) | is.na(shift(v,2))), by = comp]
comp V1
1: a 1
2: a 2
3: b 1
4: b 2
5: c 1
正如预期的那样,唯一不包括的行是comp = a和prc = 4的行。现在我该怎么做才能对该行进行数学运算。请注意,我不想删除其余行,因为它们将用于计算所需行。
答案 0 :(得分:1)
可能有帮助
dt[dt[, .I[seq_len(.N)>=3], comp]$V1]
# comp prc ret cap
#1: a 4 -0.02 300
如果目的不是为了子集,而是为了新列,请说“标记”显示TRUE / FALSE值
dt[, Flag := seq_len(.N)>=3, comp]
答案 1 :(得分:0)
dt[, which(is.na(shift(prc, 2)) | is.na(shift(ret, 1)) | is.na(shift(cap, 2))), by = comp]
# comp V1
#1: a 1
#2: a 2
#3: b 1
#4: b 2
#5: c 1
选择每个组中不满足要求的所有行。 (注意,在原始代码中,OP引用了v
,它不存在于数据集中)。
否定,
dt[, which(!(is.na(shift(prc, 2)) | is.na(shift(ret, 1)) | is.na(shift(cap, 2)))), by = comp]
# comp V1
#1: a 3
选择满足要求的每个组中的所有行。
dt[, .SD[!is.na(shift(prc, 2)) & !is.na(shift(ret, 1)) & !is.na(shift(cap, 2))], by = comp]
# comp prc ret cap
#1: a 4 -0.02 300
返回原始data.table的所有行,它们满足包括所有列的条件。
请注意:(a)布尔代数已用于将条件!(A | B | C)
替换为!A & !B & !C
,并且(b)对which()
的调用已被视为多余。
The solution of akrun可以通过类似方式简化。而不是
dt[dt[, .I[seq_len(.N)>=3], comp]$V1]
我们可以写
dt[, .SD[seq_len(.N) >= 3L], comp]
请注意,两种方法 不完全等效。虽然后一种方法只是显示每个comp
的所有行,这些行至少有两行,但第一种方法还检查NA
的内容,我认为这些内容更可靠。