swo*_*olf 11 r data.table
我无法理解这个非常简单的任务,阅读本网站上的相关问题并没有帮助.
我创建了一个最小的例子:
a <- data.table(n = c("case1", "case2", "case3"), x = c(0,2,5), y = c(1,1,4), z = c(1,1,0))
cols <- c("x", "y", "z")
a
n x y z
1: case1 0 1 1
2: case2 2 1 1
3: case3 5 4 0
Run Code Online (Sandbox Code Playgroud)
我想要做的就是从a名称保存在的列中的所有值中选择所有行都在cols0以上.
所以我想在这种情况下得到的是:
n x y z
2: case2 2 1 1
Run Code Online (Sandbox Code Playgroud)
我使用了apply with all(),但我认为data.table有一个更快的方法来做到这一点.我的原始数据当然要大得多,cols包含80个列名.谢谢你的帮助!
===编辑===
谢谢您的回答!所有这些都有效,但显然性能不同.请检查已接受答案的评论以获得基准.实现这一目标的最快方法是:
a[ a[, do.call(pmin, .SD) > 0, .SDcols=cols] ]
Run Code Online (Sandbox Code Playgroud)
我还使用rbenchmark软件包和我的原始数据集复制了不同解决方案的基准,参数略有不同(880,000行,64列,其中62个被选中)并且可以确认不同解决方案的速度等级(已经进行了10次重复) :
z[z[, !Reduce(`+`, lapply(.SD, `<`, 11)),.SDcols = col.names]]:3.32秒
z[apply(z[, col.names, with = FALSE], 1, function(x) all(x>10))]:37.41秒
z[ z[, do.call(pmin, .SD) > 10, .SDcols=col.names] ]:2.03秒
z[rowSums(z[, lapply(.SD, `<`, 11), .SDcols=col.names])==0]:4.84秒
再次谢谢你!
我们可以使用Reduce同.SDcols.指定感兴趣的列.SDcols,循环遍历Data.table(.SD)的子集,检查它是否等于0,得到每行的总和Reduce,否定(!)得到一个逻辑向量,当没有0个元素时返回TRUE用它来对"a"行进行子集化
a[a[, !Reduce(`+`, lapply(.SD, `<=`, 0)),.SDcols = cols]]
# n x y z
#1: case2 2 1 1
Run Code Online (Sandbox Code Playgroud)
或者像评论中提到的@Frank一样,pmin也可以使用
a[a[, do.call(pmin, .SD), .SDcols = cols]>0]
Run Code Online (Sandbox Code Playgroud)
你可以试试
a[rowSums(a[, lapply(.SD, `<=`, 0), .SDcols=cols])==0]
# n x y z
#1: case2 2 1 1
Run Code Online (Sandbox Code Playgroud)
它选择没有cols值小于或等于零的列的行(您也可以使用条件x> 0并检查==length(cols)是否愿意)。