【问题标题】:A replacement for `subset()` for a list of data.framesdata.frames 列表的 `subset()` 的替代品
【发布时间】:2020-02-17 00:18:04
【问题描述】:

函数foo1 可以通过一个或多个请求的变量(例如by = ESL == 1by == ESL == 1 & type == 4)子集(使用subset())data.frames 列表。

但是,我知道 R 中的 danger of using subset()。因此,我想知道在下面的 foo1 中,我可以使用什么来代替 subset() 来获得相同的输出?

foo1 <- function(data, by){

  s <- substitute(by)
  L <- split(data, data$study.name) ; L[[1]] <- NULL

  lapply(L, function(x) do.call("subset", list(x, s))) ## What to use instead of `subset`
                                                       ## to get the same output?
}

# EXAMPLE OF USE:
D <- read.csv("https://raw.githubusercontent.com/izeh/i/master/k.csv", header=TRUE) # DATA
foo1(D, ESL == 1) 

【问题讨论】:

    标签: r list function dataframe subset


    【解决方案1】:

    我猜(基于常识和对"dangers of subset()" question 答案的快速浏览)subset 的危险是非标准评估的内在危险(NSE);如果您希望能够传递通用表达式并在数据框的上下文中对其进行评估,我认为您或多或少会被 subset() 或类似的东西所困扰。

    如果您愿意使用更受约束的表达式集,例如 varvals(寻找由字符串 var 索引的变量在向量 vals 中取值的情况),您可以使用

    d[d[[var]] %in% vals, ]
    

    这里var是一个字符串,而不是一个裸露的R符号("cyl"而不是cyl);您想从数据框中提取它是明确的。

    您可以将其扩展到变量向量和值向量列表:

    for (i in seq_along(vars)) {
       d <- d[d[[vars[i]]] %in% vals[[i]], ]
    }
    

    但如果您想要表达式的完全灵活性(例如,能够使用 ESL == 1 &amp; type == 4ESL == 1 | type == 4,或基于数值变量的不等式),我认为您会被基于 NSE 的方法所困扰。

    可以想象,新的“整洁评估”机制(在 rlang 包中,详细记录了 here)会给你一个稍微更有原则的方法,但我认为危险不会完全走开。

    【讨论】:

      【解决方案2】:

      您可以根据语言进行计算。基于我对"Working with substitute after $ sign in R" 的回答:

      foo1 <- function(data, by){
      
        s <- substitute(by)
        L <- split(data, data$study.name) ; L[[1]] <- NULL
      
        E <- quote(x$a)
        E[[3]] <- s[[2]]
        s[[2]] <- E
      
        eval(bquote(lapply(L, function(x) x[.(s),])))
      }
      
      foo1(D, ESL == 1) 
      

      对于任意子集表达式,这变得更加复杂。您需要一个递归函数来抓取解析树并在正确的位置插入对$ 的调用。

      就我个人而言,我只会使用包 data.table,因为这更容易,因为您不需要 $,即,您可以在不更改 s 的情况下执行 eval(bquote(lapply(L, function(x) setDT(x)[.(s),])))。 OTOH,我根本不会这样做。在子集之前真的没有理由分裂。

      【讨论】:

        猜你喜欢
        • 2018-11-08
        • 1970-01-01
        • 2012-05-13
        • 1970-01-01
        • 2015-05-04
        • 2012-10-09
        • 1970-01-01
        • 1970-01-01
        • 2012-11-02
        相关资源
        最近更新 更多