使用data.table

时间:2018-10-23 12:24:07

标签: r data.table

要为分类变量的每个级别(或级别组合)计算一列计数,可以使用data.table语法 像这样:

#setting up the data so it's pasteable
df <- data.table(var1 = c('dog','cat','dog','cat','dog','dog','dog'),
                 var2 = c(1,5,90,95,91,110,8),
                 var3 = c('lamp','lamp','lamp','table','table','table','table'))

#adding a count column for var1
df[, var1count := .N, by = .(var1)]

#adding a count of each combo of var1 and var3
df[, var1and3comb := .N, by = .(var1,var3)]

我很好奇如何生成一个count列,该列对具有var2的每个值在+-5之间的值的记录数进行计数。

在我无法正常工作的尝试中,

df[, var2withinrange := .N, by = .(between((var2-5),(var2+5),var2))]

我得到一列记录总数,而不是期望的结果。我希望第一行的值保持为2,因为1和5属于该范围。第2行的值应为3,因为1、5和8都在5的范围内,依此类推。

非常感谢您提出解决方案。理想的是使用data.table代码!

2 个答案:

答案 0 :(得分:2)

使用的解决方案:

df[, var2withinrange := df[.(var2min = var2 - 5, var2plus = var2 + 5)
                           , on = .(var2 >= var2min, var2 <= var2plus)
                           , .N
                           , by = .EACHI][, N]][]

给出:

> df
   var1 var2  var3 var2withinrange
1:  dog    1  lamp               2
2:  cat    5  lamp               3
3:  dog   90  lamp               3
4:  cat   95 table               3
5:  dog   91 table               3
6:  dog  110 table               1
7:  dog    8 table               2

答案 1 :(得分:0)

您的版本存在的问题是它会汇总布尔值。每行将产生一个FALSE,因为每个值-5位于其值+ 5及其值之外。如果您将其更改为

between(var2, var2 - 5, var2 + 5)

您会得到TRUE,但由于矢量化版本,每列仍然为7。

您可以用sapply解决您的问题,该方法按值取值并将其与向量化列中的每个值进行比较。这可行,但主要不是data.table代码。

df$var2withinrange = sapply(df$var2, function(x){ sum(between(x, df$var2 - 5, df$var2 + 5)) })