【问题标题】:R: subset from a matrix only those rows with a certain value in a certain columnR:矩阵中的子集,仅在特定列中具有特定值的那些行
【发布时间】:2012-03-19 13:37:15
【问题描述】:

对于一组诊断代码,我有一个大型矩阵“dt”,其中包含 2 个月以上的急诊科就诊。列是“age”、“sex”、“date”、“county”、“zip”、“subjectid”、“position”、“diag”和“dt”;尺寸为 872344 x 9。

我想从该矩阵中提取子集并创建一个新矩阵,该矩阵仅包含“diag”列的数字介于 800 和 849 之间的那些行(所有列)。

我一直在搞乱构建循环并使用“which”或“if.else”,但我遇到了心理障碍。如果我只想提取一个诊断代码似乎会更容易,但是这一系列 50 个代码使事情变得复杂......指向一个循环?有没有人知道如何根据找到某些值进行子集化?

这是我的开始(没用):

dta = dt
b = 800:849
for (i in 1:length(b)) {

}

【问题讨论】:

    标签: r loops subset


    【解决方案1】:

    我不会将matrix() 转换为data.frame(),因为它速度较慢并且会占用更多内存,而matrix() 操作通常会更快。

    除了大卫使用列号索引的答案:

    dta = dt[dt[,8] >= 800 & dt[,8] <= 849,]
    

    还有一种使用矩阵的列名索引的形式:

    dta = dt[dt[,'metric'] >= 800 & dt[,'metric'] <= 849,]
    

    microbenchmark package 命令所示,对于具有 12 列和 13,241 行的相同矩阵,使用经过英特尔 MKL 优化编译的 R 运行:

    microbenchmark::microbenchmark(
         test.matrix     = mt[mt[,3] %in% 5:10 & mt[,5] == 1,],
         test.data.frame = df[df[,3] %in% 5:10 & df[,5] == 1,],
         times = 1000
         )
    
    Unit: microseconds
                expr      min       lq     mean  median        uq        max neval
     test.matrix      885.732  938.386 1154.898  943.74  952.4415 138215.318  1000
     test.data.frame 1176.218 1245.826 1363.379 1258.32 1286.4320 3392.556    1000
    

    当矩阵变得非常大时,这种差异就会变得明显。在我的机器上,矩阵索引速度也优于data.table

    【讨论】:

      【解决方案2】:

      除了上面的优秀答案,我还可以在dpylr包中添加filter函数

      filter(dt,diag>=800 & diag <= 849)
      

      filter()subset() 相似,只是你可以给它任意数量的过滤条件,这些条件与&amp; 结合在一起(不是&amp;&amp;,这很容易意外!)。 dpylr 包还有其他不错的数据处理函数,你可以看看。

      【讨论】:

        【解决方案3】:
        dta = dt[dt[, 8] >= 800 & dt[, 8] <= 849, ]
        

        ETA:你确定这是一个矩阵而不是一个 data.frame 吗?如果是data.frame,可以这样做:

        dta = dt[dt$diag >= 800 & dt$diag <= 849, ]
        

        【讨论】:

          【解决方案4】:

          鉴于您的列名,我怀疑您的 dt 是 data.frame,而不是矩阵;您可以通过运行is.data.frame(dt) 来确认。

          如果是这种情况,过滤数据的一种简单方法是使用subset 函数,如下所示:

          dta <- subset(dt, diag >= 800 & diag <= 849)
          

          【讨论】:

          • 你是对的——它是一个数据框。我想我从来不理解 R 语言的区别。谢谢!
          猜你喜欢
          • 2018-10-20
          • 1970-01-01
          • 2020-12-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-29
          相关资源
          最近更新 更多