R data.table 超过阈值的总列数
R data.table sum number of columns exceeding threshold
我想对观察中值超过阈值的列数求和。此外,我想将这些列名称和阈值指定为向量 (cols
, th
)
以示例数据集为例:
x <- data.table(x1=c(1,2,3),x2=c(3,2,1))
目标是创建一个新列 exceed.count
,其中 x1 和 x2 超过相应阈值的列数。假设x1和x2的阈值都是2的情况:
th <- c(2,2)
函数可以定义为:
fn <- function(z,th) (sum(z[,x1]>th[1],z[,x2]>th[2]))
以及超过阈值的列数计算方式:
x[,exceed.count:=fn(.SD,th),by=seq_len(nrow(x))]
结果是:
x1 x2 exceed.count
1: 1 3 1
2: 2 2 0
3: 3 1 1
我想做的是能够将列名指定为向量,例如
cols <- c("x1","x2")
我正在玩弄以下形式的函数:
fn.i <- function(z,i) (sum(z[,cols[i],with=FALSE] > th[i]))
这适用于单个 i,但我如何跨 cols 元素对其进行矢量化? (cols
和 th
的长度始终相同)
我认为有更简单的方法可以解决您的问题:
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]
@JonnyCrunch 的方法,用 .SDcols=sd.cols
指定列的子集可以正常工作(只要确保 ncol(x) == length(th)
,否则向量回收会搞砸)。
这是一个语法较短的替代方法(但对于非常宽的列而言性能会较低):
x[,exceed.count:=sum(.SD>th), by=seq_len(nrow(x)) ]
- 无需显式指定
.SDcols
,让它默认为所有列
- 为所有列定义阈值向量
th
,在您不想计算的那些列中使用无关值 +Inf
。
.
> 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
我想对观察中值超过阈值的列数求和。此外,我想将这些列名称和阈值指定为向量 (cols
, th
)
以示例数据集为例:
x <- data.table(x1=c(1,2,3),x2=c(3,2,1))
目标是创建一个新列 exceed.count
,其中 x1 和 x2 超过相应阈值的列数。假设x1和x2的阈值都是2的情况:
th <- c(2,2)
函数可以定义为:
fn <- function(z,th) (sum(z[,x1]>th[1],z[,x2]>th[2]))
以及超过阈值的列数计算方式:
x[,exceed.count:=fn(.SD,th),by=seq_len(nrow(x))]
结果是:
x1 x2 exceed.count
1: 1 3 1
2: 2 2 0
3: 3 1 1
我想做的是能够将列名指定为向量,例如
cols <- c("x1","x2")
我正在玩弄以下形式的函数:
fn.i <- function(z,i) (sum(z[,cols[i],with=FALSE] > th[i]))
这适用于单个 i,但我如何跨 cols 元素对其进行矢量化? (cols
和 th
的长度始终相同)
我认为有更简单的方法可以解决您的问题:
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]
@JonnyCrunch 的方法,用 .SDcols=sd.cols
指定列的子集可以正常工作(只要确保 ncol(x) == length(th)
,否则向量回收会搞砸)。
这是一个语法较短的替代方法(但对于非常宽的列而言性能会较低):
x[,exceed.count:=sum(.SD>th), by=seq_len(nrow(x)) ]
- 无需显式指定
.SDcols
,让它默认为所有列 - 为所有列定义阈值向量
th
,在您不想计算的那些列中使用无关值+Inf
。
- 无需显式指定
.
> 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