【问题标题】:How to subset data.table on the basis of a values in a certain column number如何根据某个列号中的值对 data.table 进行子集化
【发布时间】:2016-03-21 02:35:36
【问题描述】:

在 data.table 中,根据列号的数字向量对表进行子集化的一种方法是使用 with=FALSE

我正在尝试根据列号的数字向量循环遍历 data.table,寻找满足特定条件的 ,如下所示:

require(data.table)

ab=data.table(id=c("geneA", "geneB", "geneC", "geneA", "geneA", "geneB", "", "NA"),
              co1=c(1,2,3,0,7), co2=c(0,0,4,5,6), nontarget=c(9,0,7,6,5), 
              co3=c(0,1,2,3,4))
target_col_nums=grep('co', colnames(ab))

##Data.table doesn't treat colnames(ab)[i] as one of the
##  column name variables, and with=F only seems to work for j in dt[i,j,by]
for (i in target_col_nums){
    print(ab[colnames(ab)[i]>3])
}

##This produces the desired output
ab[co1>3]
ab[co2>3]
ab[co3>3]

在我的情况下,我的实际表很大,所以我不能自己使用列名。

我希望这是一个对社区有用的问题。

【问题讨论】:

  • 您知道您的示例数据会产生警告吗?
  • "我的实际表非常大,所以我不能自己使用列名。"这对我来说没有意义。如果您的列名没有意义,请继续使用矩阵,否则,我认为它们属于字符串/字符向量,而不是被数字引用。在此处查看 1.1,了解为什么通常建议这样做 rawgit.com/wiki/Rdatatable/data.table/vignettes/…

标签: r data.table


【解决方案1】:
for (col in grep('co', names(ab), value = T))
  print(ab[get(col) > 3])
#      id co1 co2 nontarget co3
#1: geneA   7   6         5   4
#      id co1 co2 nontarget co3
#1: geneC   3   4         7   2
#2: geneA   0   5         6   3
#3: geneA   7   6         5   4
#4:    NA   3   4         7   2
#      id co1 co2 nontarget co3
#1: geneA   7   6         5   4

【讨论】:

  • 基本上是我的更时髦的版本! value 论点的绝佳例证
【解决方案2】:

您可以将 (eval) 列评估为表达式

for (i in target_col_nums){
    expr <- paste0(colnames(ab)[i], ">3")
    print(ab[eval(parse(text = expr)), ])
}

#      id co1 co2 nontarget co3
#1: geneA   7   6         5   4
#      id co1 co2 nontarget co3
#1: geneC   3   4         7   2
#2: geneA   0   5         6   3
#3: geneA   7   6         5   4
#4:    NA   3   4         7   2
#      id co1 co2 nontarget co3
#1: geneA   7   6         5   4

或者您可以尝试问题passing variables as data.table column names中的任何建议

【讨论】:

  • 还不如expr &lt;- parse(text=paste0("print(ab[", names(ab)[target_col_nums], "&gt;3])"))。然后可以做sapply(expr, eval)。 `
【解决方案3】:

您的方法可以非常轻微地调整,并且仍然可以使用列号(虽然在这种情况下由于您以编程方式获取数字,但在这种情况下并没有那么有害,但通常是不好的做法):

target_cols = names(ab)[grepl("co", names(ab))]

sapply(target_cols, function(jj) print(ab[get(jj) > 3]))

如果NULL 输入会分散您的注意力/否则会打扰您,请输入invisible

【讨论】:

    【解决方案4】:

    我们可以在.SDcols 中指定'i',并使用.SD 上的条件得到一个逻辑向量,该向量可用于对行进行子集化。

    for(i in target_col_nums){
     print(ab[ab[, .SD[[1L]] >3, .SDcols = i]])
    }
    #         id co1 co2 nontarget co3
    #1: geneA   7   6         5   4
    #      id co1 co2 nontarget co3
    #1: geneC   3   4         7   2
    #2: geneA   0   5         6   3
    #3: geneA   7   6         5   4
    #4:    NA   3   4         7   2
    #      id co1 co2 nontarget co3
    #1: geneA   7   6         5   4
    

    【讨论】:

      猜你喜欢
      • 2017-12-23
      • 2019-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-24
      相关资源
      最近更新 更多