【问题标题】:Manipulate columns by their name pattern in a R data table在 R 数据表中按名称模式操作列
【发布时间】:2015-03-25 16:57:58
【问题描述】:

我有一个数据表,DT;它的一些列名有一个模式。我怎样才能简洁地(即在一行代码中)写出类似

DT[pat1>0, pat1:=1]
DT[pat2>0, pat2:=1]
DT[pat3>0, pat3:=1]

玩具数据:

require(data.table)
set.seed(1)
DT <- data.table(id=rnorm(5), pat1=sample(0:3, 5, T), pat2=sample(0:3, 5, T), pat3=sample(0:3, 5, T))
DT
##            id pat1 pat2 pat3
## 1: -0.6264538    0    1    3
## 2:  0.1836433    0    2    0
## 3: -0.8356286    2    3    2
## 4:  1.5952808    1    1    0
## 5:  0.3295078    3    3    1


DT[pat1>0, pat1:=1]
DT[pat2>0, pat2:=1]
DT[pat3>0, pat3:=1]
DT
##            id pat1 pat2 pat3
## 1: -0.6264538    0    1    1
## 2:  0.1836433    0    1    0
## 3: -0.8356286    1    1    1
## 4:  1.5952808    1    1    0
## 5:  0.3295078    1    1    1    

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    如果它必须在一行,这个循环会做:

    for (j in paste0('pat',1:3)) DT[get(j) > 0, (j) := 1L]
    

    【讨论】:

    • 我接受这个,因为它最容易阅读。 @nicola 的回答也很棒,明确的 function(x) 使代码更容易被回收。我将测试哪一个在执行时间方面表现最好(我的猜测是 nicola 的)。我突然想到一个随机想法:如果data.table 的未来版本有更多的包装函数,那就太好了。
    • 我的猜测是 akrun 的速度也会比我的快,尤其是当您增加修改的列数时。像 nicola's 一样,akrun's 不会像我的那样在循环中重复调用 [.data.table。 (如果是这样,我的答案的唯一相对优点是它的可读性。)我不确定在这种情况下你所说的包装函数是什么意思,但dplyr 似乎有大量适用于@987654326 的特殊用途函数@s;我希望尽快学习/尝试它的语法。
    【解决方案2】:

    你也可以试试set

    indx <- grep('pat', names(DT))
    
    for(j in indx){set(DT, i= which(DT[[j]] >0), j=j, value=1) }
    
     DT
     #           id pat1 pat2 pat3
     #1: -0.6264538    0    1    1
     #2:  0.1836433    0    1    0
     #3: -0.8356286    1    1    1
     #4:  1.5952808    1    1    0
     #5:  0.3295078    1    1    1
    

    另外,正如@Frank 所说,'indx' 对象不是必需的,因为它可以在for 循环中使用。

    【讨论】:

    • 并且.. 作为一个班轮(根据 OP 的要求):for(j in grep('pat',names(DT))) set(DT, i= which(DT[[j]] &gt;0), j=j, value=1)
    • @Frank 谢谢,我考虑过,但是单行会有点拥挤。
    【解决方案3】:

    试试:

    DT[,paste0("pat",1:3):=lapply(.SD,function(x) as.integer(x>0)),.SDcols=paste0("pat",1:3)]
                id pat1 pat2 pat3
    #1: -0.6264538    0    1    1
    #2:  0.1836433    0    1    0
    #3: -0.8356286    1    1    1
    #4:  1.5952808    1    1    0
    #5:  0.3295078    1    1    1
    

    【讨论】:

    • 子集,通过使用DT[i,j]i 部分,在速度方面可能是有益的。
    • @eddi 啊,我想我错了。我认为只加载需要编辑的子集到.SD 会节省时间,但这里的编辑并非如此。 akrun 的答案中的set 方法是正确的方法,对吧?
    • @Frank 我不确定这里的“正确”是什么意思——所有 3 个选项都有效并且各有优缺点;这个特别的是我通常做的,但这并不意味着什么
    猜你喜欢
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 2022-12-07
    • 2014-05-31
    相关资源
    最近更新 更多