R 使用data.table对每行中指定值范围内的值进行计数

R 使用data.table对每行中指定值范围内的值进行计数,r,data.table,R,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','tabl

为分类变量的每个级别(或级别组合)提供一列计数是数据 比如:

#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)]
我得到一个列,其中记录的总数与期望的结果相反。我希望第一行的值为2,因为1和5属于这个范围。第2行的值应为3,因为1、5和8都属于5的范围,依此类推


非常感谢您在提出解决方案时提供的任何帮助。最好是在data.table代码中

您的版本的问题在于它聚合了布尔值。每一行都会产生一个FALSE,因为每个值-5都位于其值+5及其值之外。如果你想把它改成

between(var2, var2 - 5, var2 + 5)
你会得到真实的回报,但仍然是一个7在每一列,因为矢量化版本

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

df$var2withinrange = sapply(df$var2, function(x){ sum(between(x, df$var2 - 5, df$var2 + 5)) })
解决方案包括:

df$var2withinrange = sapply(df$var2, function(x){ sum(between(x, df$var2 - 5, df$var2 + 5)) })
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