【问题标题】:Subset using column name defined using paste0 and a variable使用使用 paste0 和变量定义的列名的子集
【发布时间】:2017-03-15 23:49:42
【问题描述】:

我有一个这样的 data.table:

dt <- data.table(asset=c("x1","x2","x3","x4","x5"),
                min_s1=c(.1,NA,NA,.1,NA),
                min_s2=c(NA,.5,.5,NA,NA),
                min_s3=c(.15,NA,NA,NA,.15))

我可以手动对 NA 值进行子集化,如下所示,这给了我想要的输出:

empty1 <- dt[is.na(min_s1)]
empty2 <- dt[is.na(min_s2)]
empty3 <- dt[is.na(min_s3)]

但是,我真正需要做的是使用列名动态地设置子集,并在循环中命名包含 i 变量的结果。循环很重要,因为它最终将用于并行计算脚本。我想要这样的东西(它不起作用;只是显示我正在寻找的东西):

foreach (i in 1:3) %do% {
  empty(i) <- dt[is.na(min_s(i))]
}

我尝试使用以下及其许多变体均无济于事:

paste0("empty",i) <- dt[is.na(paste0("min_s",i))]

有什么想法可以做到这一点吗? 我使用的是 Windows 7 电脑。 谢谢。

【问题讨论】:

    标签: r parallel-processing data.table


    【解决方案1】:

    我们可以使用 lapply 循环遍历“min”列并子集数据集

    lapply(dt[,-1, with =FALSE], function(x) dt[is.na(x)])
    #$min_s1
    #   asset min_s1 min_s2 min_s3
    #1:    x2     NA    0.5     NA
    #2:    x3     NA    0.5     NA
    #3:    x5     NA     NA   0.15
    
    #$min_s2
    #   asset min_s1 min_s2 min_s3
    #1:    x1    0.1     NA   0.15
    #2:    x4    0.1     NA     NA
    #3:    x5     NA     NA   0.15
    
    #$min_s3
    #   asset min_s1 min_s2 min_s3
    #1:    x2     NA    0.5     NA
    #2:    x3     NA    0.5     NA
    #3:    x4    0.1     NA     NA
    

    【讨论】:

    • 这很好用并且是非常简单的代码。感谢您对此的帮助以及我所依赖的许多其他有用的答案!
    【解决方案2】:

    希望我正确理解了您的问题,因此请尝试以下操作:

       dt <- data.table(asset=c("x1","x2","x3","x4","x5"),
                     min_s1=c(.1,NA,NA,.1,NA),
                     min_s2=c(NA,.5,.5,NA,NA),
                     min_s3=c(.15,NA,NA,NA,.15))
    
    vec_store <- c()
    empty <- list()
    names <- names(dt)[!grepl("asset", names(dt))]
    
    
    for(i in names){
      vec_store <- dt[is.na(dt[,get(i)])]
      empty[[paste0(i)]] <- vec_store
    }
    

    这给了你:

    > empty
    $min_s1
       asset min_s1 min_s2 min_s3
    1:    x2     NA    0.5     NA
    2:    x3     NA    0.5     NA
    3:    x5     NA     NA   0.15
    
    $min_s2
       asset min_s1 min_s2 min_s3
    1:    x1    0.1     NA   0.15
    2:    x4    0.1     NA     NA
    3:    x5     NA     NA   0.15
    
    $min_s3
       asset min_s1 min_s2 min_s3
    1:    x2     NA    0.5     NA
    2:    x3     NA    0.5     NA
    3:    x4    0.1     NA     NA
    

    在您的代码中,您不能使用paste0(empty,i) 创建对象,我发现最简单的方法是创建一个空向量或data.table,然后将其存储在一个列表中。一旦它在列表中,您就可以对列表进行操作,或者将其单独从列表中拉出。这就是为什么我创建了vec_store 一个空向量和empty 一个空列表。

    希望对您有所帮助。

    【讨论】:

    • 这行得通。谢谢您的帮助。 Akrun 的答案稍微简单一点,结果相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 2013-06-09
    相关资源
    最近更新 更多