如何选择多列作为行选择的条件

时间:2017-09-05 12:20:40

标签: r data.table

例如,

set.seed(1984)
d <- data.table(name=letters[1:26],a=rbinom(26,1,0.5),b=rbinom(26,1,0.5),c=rbinom(26,1,0.5))

我可以删除a,b,c列为0的行:

d[,if(sum(a,b,c) != 0) .SD,by=.(a,b,c)]

结果是:

   a b c name
 1: 1 1 1    a
 2: 1 1 1    u
 3: 1 1 1    x
 4: 0 1 0    b
 5: 0 1 0    d
 6: 0 1 0    h
 7: 0 1 1    c
 8: 0 1 1    g
 9: 0 1 1    o
10: 0 1 1    q
11: 0 1 1    t
12: 1 1 0    e
13: 1 1 0    k
14: 1 1 0    y
15: 1 0 0    f
16: 1 0 0    i
17: 1 0 0    r
18: 1 0 0    s
19: 1 0 0    w
20: 0 0 1    j
21: 0 0 1    v
22: 1 0 1    m
23: 1 0 1    n
    a b c name

现在,我有两个问题:

  1. 如何将“名称”列保留为第一列?
  2. 如何选择a,b,c列作为简单表达式(如:c,但a:c不代表a,b,c)?如果有数百列,我不能在sum函数中输入无穷无尽的a,b,c ......或者是by的参数。
  3. 添加问题:

    如果它不是sum(具有用于处理行的rowSums版本)但是其他函数如max,如何在没有应用函数族的情况下重新调用问题1和2(应用函数族是针对数据框设计的,我担心它们会减少数据表的速度)。

2 个答案:

答案 0 :(得分:2)

我们可以将Reduce+一起使用,根据.SDcols

中指定的列创建逻辑向量
d[d[, Reduce(`+`, .SD) != 0, .SDcols = a:c]]

其他选项包括(@ nicola's)

d[Reduce("+",d[,a:c])!=0]

或者@Frank建议使用pmax根据每行上的最大值创建一个列('keep'),将其从二进制转换为logical并基于该子集行和列

d[, keep := as.logical(do.call(pmax, .SD)), .SDcols=!"name"][(keep), !"keep"]

答案 1 :(得分:1)

您还可以使用rowSums功能:

 d[rowSums(d[,2:4])!=0,]