简体   繁体   English

按 function 参数过滤 data.tables 列表

[英]Filter list of data.tables by function argument

I'm writing on a function that should filter each data.table in a list.我正在写一个 function 应该过滤列表中的每个data.table

An Example:一个例子:

library(purrr)
library(magrittr)
library(data.table)

My.List <- 
  as.data.table(iris) %>% 
  split(by = "Species")

map(My.List, ~.x[Sepal.Length < 5.5])

That is exactly what I want my result to be.这正是我想要的结果。 But the function should be very user friendly.但是 function 应该非常用户友好。 This is my desired function and it was even better if I could have multiple conditions separated by a , , like in dplyr 's filter :这是我想要的 function ,如果我可以有多个条件由 , 分隔,那就更好了,就像在dplyrfilter中一样:

myfunction(My.List, Sepal.Length < 5.5)
myfunction(My.List, Sepal.Length < 5.5, Petal.Width > 1)

Technically, this is called Non Standard Evaluation nse .从技术上讲,这称为非标准评估nse For the tidyverse, you could check here for the NSE implementation对于 tidyverse,您可以在此处查看 NSE 实施

Anyway to answer your question:无论如何回答你的问题:

library(tidyverse)
myfunction <- function(lst, ...){
  nms <- enquos(...)
  map(lst, ~filter(.x, !!!nms))
}

myfunction(My.List, Sepal.Length < 5.5)
myfunction(My.List, Sepal.Length < 5.5, Petal.Width > 1)

If interested in ONLY BASE R functions, you could do:如果只对 BASE R 功能感兴趣,您可以这样做:

myfunction <- function(lst, ...){
  nms <- substitute(list(...))
  lapply(lst, function(x)x[Reduce("&", eval(nms, x)),])
 }

Here's a base R equivalent that also does the trick.这是一个基本的 R 等价物,它也可以解决问题。 It uses match.call to extract the expressions (if there are any), then uses lapply to iterate through the list, evaluating each expression in the context of each data frame in the list using eval .它使用match.call提取表达式(如果有的话),然后使用lapply遍历列表,使用eval在列表中每个数据帧的上下文中评估每个表达式。 This produces a list of logical vectors for each data frame, which are then combined into a single vector with an "&" via Reduce .这会为每个数据帧生成一个逻辑向量列表,然后通过Reduce这些逻辑向量组合成一个带有“&”的向量。 This subsets each data frame.这对每个数据帧进行了子集化。

myfunction <- function(.list, ...)
{
  mc <- as.list(match.call())[-1]
  if(length(mc) == 1) return(.list)
  lapply(.list, function(df)
  {
    conds <- lapply(mc[-1], function(condition) eval(condition, envir = df))
    df[Reduce("&", conds),]
  })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM