要为分类变量的每个级别(或级别组合)计算一列计数,可以使用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代码!
答案 0 :(得分:2)
使用data.table的解决方案:
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)) })