R数据表超过阈值的列总数

R数据表超过阈值的列总数,r,data.table,vectorization,threshold,R,Data.table,Vectorization,Threshold,我想对观察值超过阈值的列数求和。此外,我想将这些列名和阈值指定为向量(cols,th) 以数据集为例: x <- data.table(x1=c(1,2,3),x2=c(3,2,1)) 该功能可定义为: fn <- function(z,th) (sum(z[,x1]>th[1],z[,x2]>th[2])) 结果是: x1 x2 exceed.count 1: 1 3 1 2: 2 2 0 3: 3 1

我想对观察值超过阈值的列数求和。此外,我想将这些列名和阈值指定为向量(
cols
th

以数据集为例:

x <- data.table(x1=c(1,2,3),x2=c(3,2,1))
该功能可定义为:

fn <- function(z,th) (sum(z[,x1]>th[1],z[,x2]>th[2]))
结果是:

   x1 x2 exceed.count
1:  1  3            1
2:  2  2            0
3:  3  1            1
我想做的是能够将列名指定为vector,例如

cols <- c("x1","x2")

cols我认为有一种更简单的方法来解决您的问题:

x<-data.table(x1=c(1,2,3),x2=c(3,2,1))
th<-c(2,2)
x[,exceed.count:=sum(.SD>th),by=seq_len(nrow(x))]

x@JonnyCrunch的方法是,使用
.SDcols=sd.cols
指定列的子集,这样做很好(只要您确保
ncol(x)==length(th)
,否则向量循环将把事情搞砸)

下面是一个较短语法的替代方案(但对于非常宽的列来说性能较差):

  • x[,except.count:=sum(.SD>th),by=seq_len(nrow(x))]
    • 无需显式指定
      .SDcols
      ,默认为所有列
    • 为所有列定义阈值向量
      th
      ,在不希望计数的列中使用不关心值
      +Inf

>x th fn th)
>x[,超过.计数:=总和(.SD>th),乘以=序号(nrow(x))]
x0 x1 x2 x3超过计数
1:  4  1  3  7            1
2:  5  2  2  6            1
3:  6  3  1  5            2

这里有一种方法可以绕过行上的迭代:

x <- data.table(x1=c(1,2,3), x2=c(3,2,1))
thL <- list(x1 = 2, x2 = 2)

nm = names(thL)
x[, n := 0L]
for (i in seq_along(thL)) x[thL[i], on=sprintf("%s>%s", nm[i], nm[i]), n := n + 1L][]

   x1 x2 n
1:  1  3 1
2:  2  2 0
3:  3  1 1

x我应该更具体地说,我正在比较的列只能是x列的子集。您的解决方案假定包含所有列。然而,这确实给了我一个想法,将x子集到我希望比较的列中,然后将结果合并回x。如果
ncol(x)!=长度(th)
,向量循环会把事情搞砸。这是真的,先生。我考虑过命名
th
值,这样我就可以只过滤
sd.cols
中的值,并创建一个
assert-alert
,按奇怪结果的顺序排列,但我认为我把问题复杂化了。无论如何,感谢您提出这个问题。使用
.SDcols=sd.cols
指定列的子集更有效。但是,只需使用所有列即可获得相同的效果,不要指定
.SDcols
,并在不希望计算的阈值的那些列中设置不关心值
+Inf
fn.i <- function(z,i) (sum(z[,cols[i],with=FALSE] > th[i]))
x<-data.table(x1=c(1,2,3),x2=c(3,2,1))
th<-c(2,2)
x[,exceed.count:=sum(.SD>th),by=seq_len(nrow(x))]
x<-data.table(x1=c(1,2,3),x2=c(3,2,1))
sd.cols = c("x1")
th<-c(2)
x[,exceed.count:=sum(.SD>th),by=seq_len(nrow(x)), .SDcols=sd.cols]
x<-data.table(x1=c(1,2,3),x2=c(3,2,1))
sd.cols = c("x1")
th<-c(2,2)
x[,exceed.count:=sum(.SD>th[1]),by=seq_len(nrow(x)), .SDcols=sd.cols]
> x <- data.table(x0=4:6, x1=1:3, x2=3:1, x3=7:5)

   x0 x1 x2 x3
1:  4  1  3  7
2:  5  2  2  6
3:  6  3  1  5

> th <- c(+Inf, 2, +Inf, 2) 

> fn <- function(z,th) (z>th)

> x[,exceed.count:=sum(.SD>th), by=seq_len(nrow(x)) ]

   x0 x1 x2 x3 exceed.count
1:  4  1  3  7            1
2:  5  2  2  6            1
3:  6  3  1  5            2
x <- data.table(x1=c(1,2,3), x2=c(3,2,1))
thL <- list(x1 = 2, x2 = 2)

nm = names(thL)
x[, n := 0L]
for (i in seq_along(thL)) x[thL[i], on=sprintf("%s>%s", nm[i], nm[i]), n := n + 1L][]

   x1 x2 n
1:  1  3 1
2:  2  2 0
3:  3  1 1