【问题标题】:Select subset of columns in data.table R [duplicate]选择data.table R中的列子集[重复]
【发布时间】:2015-03-21 14:11:37
【问题描述】:

我有一个包含一堆列的数据表,例如:

dt<-data.table(matrix(runif(10*10),10,10))

我想对数据表进行一些操作,比如生成一个相关矩阵(cor(dt))。为此,我想删除一些包含非数字值或超出特定范围的值的列。

假设我想找到不包括 V1、V2、V3 和 V5 的相关矩阵。

这是我目前的做法:

cols<-!(colnames(dt)=="V1" | colnames(dt)=="V2" | colnames(dt)=="V3" | colnames(dt)=="V5")
new_dt<-subset(dt,,cols)
cor(new_dt)

考虑到 data.table 语法通常如此优雅,我觉得这很麻烦。有没有更好的方法来做到这一点?

【问题讨论】:

  • 您可以使用%in%,而不是==!colnames(dt) %in% paste0('V', c(1:2,3,5))

标签: r data.table


【解决方案1】:

使用with=FALSE:

cols = paste("V", c(1,2,3,5), sep="")

dt[, !cols, with=FALSE]

我建议通过"Introduction to data.table" 小插图。


更新:v1.10.2 开始,您还可以这样做:

dt[, ..cols]

请参阅 v1.10.2 here 下的第一个 NEWS 项目以获取更多说明。

【讨论】:

  • 为了避免with = FALSE,您还可以像这样使用.SD:dt[, .SD, .SDcols = cols],它将返回您在cols 中输入的列定义的数据子集。我发现这更容易以编程方式实现。
  • 很好,但为什么要避免with=FALSE?编程有多难?您在 .SDcolswith=FALSE 中都传递了一个字符向量。
  • 对不起 - 旨在澄清这对我来说更容易记住。我永远不记得什么时候必须引用,什么时候不需要引用,因此什么时候使用with=FALSE,什么时候不使用。我发现这段代码比使用 with=FALSE 时更具可读性,因为我不必记住为什么要“关闭”data.table 的一个不错的功能——不必引用列名。
  • 我明白了。如果有帮助的话,它与基础 R 中的with() 非常相似。我了解.SDcols 对您来说很方便,这很好。虽然我不禁觉得 可读性 的问题,由于某种原因,最近在 R 编程中通过放大镜看到了,尤其是在涉及 data.table 和 dplyr 语法时。
【解决方案2】:

你可以的

dt[, !c("V1","V2","V3","V5")]

得到

            V4         V6         V7        V8         V9        V10
 1: 0.88612076 0.94727825 0.50502208 0.6702523 0.24186706 0.96263313
 2: 0.11121752 0.13969145 0.19092645 0.9589867 0.27968190 0.07796870
 3: 0.50179822 0.10641301 0.08540322 0.3297847 0.03643195 0.18082180
 4: 0.09787517 0.07312777 0.88077548 0.3218041 0.75826099 0.55847774
 5: 0.73475574 0.96644484 0.58261312 0.9921499 0.78962675 0.04976212
 6: 0.88861117 0.85690337 0.27723130 0.3662264 0.50881663 0.67402625
 7: 0.33933983 0.83392047 0.30701697 0.6138122 0.85107176 0.58609504
 8: 0.89907094 0.61389815 0.19957386 0.3968331 0.78876682 0.90546328
 9: 0.54136123 0.08274569 0.25190790 0.1920462 0.15142604 0.12134807
10: 0.36511064 0.88117171 0.05730210 0.9441072 0.40125023 0.62828674

【讨论】:

    【解决方案3】:

    另一种选择是使用.SDcols

    cols = paste0("V", c(1,2,3,5))
    dt[, .SD, .SDcols=-cols]
    

    【讨论】:

      【解决方案4】:

      这似乎是一种改进:

      > cols<-!(colnames(dt) %in% c("V1","V2","V3","V5"))
      > new_dt<-subset(dt,,cols)
      > cor(new_dt)
                  V4          V6          V7          V8         V9         V10
      V4   1.0000000  0.14141578 -0.44466832  0.23697216 -0.1020074  0.48171747
      V6   0.1414158  1.00000000 -0.21356218 -0.08510977 -0.1884202 -0.22242274
      V7  -0.4446683 -0.21356218  1.00000000 -0.02050846  0.3209454 -0.15021528
      V8   0.2369722 -0.08510977 -0.02050846  1.00000000  0.4627034 -0.07020571
      V9  -0.1020074 -0.18842023  0.32094540  0.46270335  1.0000000 -0.19224973
      V10  0.4817175 -0.22242274 -0.15021528 -0.07020571 -0.1922497  1.00000000
      

      这个不太容易掌握,但可能适用于需要通过数字向量指定列的情况:

      subset(dt, , !grepl(paste0("V", c(1:3,5),collapse="|"),colnames(dt) ))
      

      【讨论】:

        【解决方案5】:

        如果不强制指定列名:

        > cor(dt[, !c(1:3, 5)])
                     V4          V6          V7         V8          V9         V10
        V4   1.00000000 -0.50472635 -0.07123705  0.9089868 -0.17232607 -0.77988709
        V6  -0.50472635  1.00000000  0.05757776 -0.2374420  0.67334474  0.29476983
        V7  -0.07123705  0.05757776  1.00000000 -0.1812176 -0.36093750  0.01102428
        V8   0.90898683 -0.23744196 -0.18121755  1.0000000  0.21372140 -0.75798418
        V9  -0.17232607  0.67334474 -0.36093750  0.2137214  1.00000000 -0.01179544
        V10 -0.77988709  0.29476983  0.01102428 -0.7579842 -0.01179544  1.00000000
        

        【讨论】:

          【解决方案6】:

          按列索引子集(避免输入他们的名字)你可以这样做

          dt[, .SD, .SDcols = -c(1:3, 5L)]
          

          结果还可以

                      V4          V6         V7         V8         V9       V10
           1: 0.51500037 0.919066234 0.49447244 0.19564261 0.51945102 0.7238604
           2: 0.36477648 0.828889808 0.04564637 0.20265215 0.32255945 0.4483778
           3: 0.10853112 0.601278633 0.58363636 0.47807015 0.58061000 0.2584015
           4: 0.57569100 0.228642846 0.25734995 0.79528506 0.52067802 0.6644448
           5: 0.07873759 0.840349039 0.77798153 0.48699653 0.98281006 0.4480908
           6: 0.31347303 0.670762371 0.04591664 0.03428055 0.35916057 0.1297684
           7: 0.45374290 0.957848949 0.99383496 0.43939774 0.33470618 0.9429592
           8: 0.99403107 0.009750809 0.78816609 0.34713435 0.57937680 0.9227709
           9: 0.62776909 0.400467655 0.49433474 0.81536420 0.01637135 0.4942351
          10: 0.10318372 0.177712847 0.27678497 0.59554454 0.29532020 0.7117959
          

          【讨论】:

            【解决方案7】:

            使用 dplyr 的选项

            require(dplyr)
            dt<-as.data.frame(matrix(runif(10*10),10,10))
            dt <- select(dt, -V1, -V2, -V3, -V4)
            cor(dt)
            

            【讨论】:

            • select(dt, -(V1:V4)),因为它们按列顺序排列。虽然我认为 OP 正在寻找 select(dt, -(V1:V3), -V5)
            猜你喜欢
            • 2012-08-10
            • 1970-01-01
            • 2016-04-20
            • 2023-03-12
            • 2019-11-16
            • 1970-01-01
            • 1970-01-01
            • 2013-01-08
            相关资源
            最近更新 更多