如果我有data.table
:
d <- data.table("ID" = c(1, 2, 2, 4, 6, 6),
"TYPE" = c(1, 1, 2, 2, 3, 3),
"CLASS" = c(1, 2, 3, 4, 5, 6))
我知道我可以删除大于特定值的值,例如:
r <- d[!(d$TYPE > 2), ]
但是,如果我要将其应用于整个表中的所有列的 all 而不是仅应用于TYPE
(基本上在整个表中删除所有值> 2的行),我将如何概括以上语句(如果可能,尽量避免使用for
循环)。
我知道我可以d > 2
生成布尔索引表,但是如果我将其放入上面的代码行中,则会给我一个错误:
d[!d>2, ]
产生invalid matrix type
注意
有人提出,这个问题类似于Return an entire row if the value in any specific set of columns meets a certain criteria。
但是,他们使用的是data.frame
,而我使用的是data.table
,表示法是不同的。因此,不是重复的问题。
答案 0 :(得分:2)
将apply
与any
一起使用
d[!apply(d>2,1,any)]
ID TYPE CLASS
1: 1 1 1
2: 2 1 2
或rowSums
d[rowSums(d>2)==0,]
ID TYPE CLASS
1: 1 1 1
2: 2 1 2
答案 1 :(得分:2)
我想知道对于不同数量的行和列,最快的方法是什么。
因此,这是一个基准。
它不检查ID
列,该列与OP的问题不完全一致,而是明智的决定,恕我直言。
library(data.table)
library(bench)
bm <- press(
n_row = c(1E1, 1E3, 1E5),
n_col = c(2, 10, 50),
{
set.seed(1L)
d <- data.table(
ID = seq_len(n_row),
matrix(sample(10, n_row*n_col, TRUE), ncol = n_col)
)
mark(
m1 = d[d[, !apply(.SD > 2, 1, any), .SDcols = -"ID"]],
m2 = d[!d[, apply(.SD > 2, 1, any), .SDcols = -"ID"]],
m3 = d[!d[, which(apply(.SD > 2, 1, any)), .SDcols = -"ID"]],
m4 = d[d[, rowSums(.SD > 2) == 0, .SDcols = -"ID"]],
m5 = d[!d[, Reduce(any, lapply(.SD, `>`, y = 2)), by = 1:nrow(d), .SDcols = -"ID"]$V1]
)
})
ggplot2::autoplot(bm)
显然,rowSums()
方法几乎总是最快的方法。