【问题标题】:R search in multiple datatable columnsR在多个数据表列中搜索
【发布时间】:2016-06-23 14:58:27
【问题描述】:

我需要根据跨多个列的条件对 data.table 进行子集化,然后对结果执行操作。

带有简单 data.table 的最小示例:

x <- data.table(id=c(1, 2, 3, 4), colour1 = c('red', 'green', 'green', 'blue'), 
                colour2 = c('yellow', 'red', 'blue', 'black'), 
                colour3 = c('blue', 'black', 'red', 'yellow'),
                score = c(0.7, 0.9, 0.2, 0.35))

然后我想找到任何包含“黄色”颜色的行的最高分:

max_score <- max(x[colour1 == 'yellow' | colour2 == 'yellow' | colour3 == 'yellow']$score)

在这个例子中,上面的代码工作正常,但是有没有更好的方法来检查多列的这个条件?在实践中,表格会更大,列数可以改变,所以我想动态地这样做。

【问题讨论】:

标签: r dataframe data.table


【解决方案1】:

这可能会让人感觉很困难,因为您的数据格式很宽(即“不整齐”)。只需使用melt 转换为长格式,非常简单。

melt(x, measure.vars = grep("^colo", names(x)))[,max(score[value == "yellow"])]
# [1] 0.7

melt(x, measure.vars = grep("^colo", names(x)))[value == "yellow", max(score)]

要查看发生了什么,请先运行它

melt(x, measure.vars = grep("^colo", names(x)))

然后是整个命令。


当然您也可以分两步完成,以防您想保留长格式以供进一步计算:

x_tidy <- melt(x, measure.vars = grep("^colo", names(x)))
x_tidy[value == "yellow", max(score)]
#[1] 0.7

【讨论】:

    【解决方案2】:

    使用 rowSums:

    max(
      x[ rowSums(x[, grepl("colour", colnames(x)), with = FALSE] == "yellow") > 0,
         "score", with = FALSE]
      )
    

    【讨论】:

      【解决方案3】:

      使用原生 R

      y=data.frame(x)
      max(y$score[apply(y[,grep("^colo", colnames(y))]=="yellow",1,any)])
      
      [1] 0.7
      

      【讨论】:

        【解决方案4】:

        另一个类似于 jangorecki 的想法(可能更简单)是简单地循环通过累积行的“逻辑”向量的列来检查 x[["score"]] 中的 max 以节省一些内存使用:

        i = logical(nrow(x))
        for(j in which(startsWith(names(x), "colour"))) i = i | x[[j]] == "yellow" 
        max(x[["score"]][i])
        #[1] 0.7
        

        【讨论】:

          【解决方案5】:

          使用 R computing on the language 功能。

          i.cols.equal <- function(cols, value) {
              l <- lapply(cols, function(col) call("==", as.name(col), value))
              Reduce(function(a, b) bquote(.(a) | .(b)), l)
          }
          ii <- i.cols.equal(cols=c("colour1", "colour2", "colour3"), value="yellow")
          print(ii)
          #colour1 == "yellow" | colour2 == "yellow" | colour3 == "yellow"
          x[eval(ii), max(score)]
          #[1] 0.7
          

          【讨论】:

            猜你喜欢
            • 2017-07-12
            • 2021-12-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-12-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多