подмножество из списка data.frames в R - PullRequest
2 голосов
/ 13 мая 2019

В моей функции ниже ... представляет любые векторы (например, numeric или character и т. Д.) с именем пользователем. Например, пользователь может определить age = 1:3 и prof = c("med", "low", "med"). Эти дополнительные векторы добавляются к data.frame, называемому out.

Мне было интересно, можно ли как-нибудь создать новый аргумент с именем extract, чтобы позволить пользователю подмножество из окончательного вывода h.

Например, если пользователь хочет установить подмножество age == 2 или age == 2 & prof == "low", соответствующее совпадение из выходных данных возвращается с использованием extract = age == 2 & prof == "low"?

foo <- function(d, per, ...){ ## Add a new argument called `extract`

 out <- data.frame(d, ...)

h <- split(out, rep(seq_along(per), per))  ## `extract` should subset from `h`
return(h)
}
# Example of use:
foo(d = 2:4, per = 1:2, age = 1:3, prof = c("med", "low", "med"))

Ответы [ 2 ]

3 голосов
/ 13 мая 2019

Это не использует никаких пакетов и не использует явно eval.

foo2 <- function(d, per, ..., extract = TRUE) {
  out <- data.frame(...)
  h <- split(out, rep(seq_along(per), per))
  s <- substitute(extract)
  lapply(h, function(x) do.call("subset", list(x, s)))
}


foo2(d = 2:4, per = 1:2, age = 1:3, prof = c("med", "low", "med"), extract = age == 2)
2 голосов
/ 13 мая 2019

Мы можем передать выражение в кавычках в 'extract' и eval uate для фильтрации строк

library(tidyverse)
foo <- function(d, per, extract, ...){ ## Add a new argument called `extract`

   extract <- rlang::enexpr(extract)
   out <- data.frame(d, ...)


  h <- split(out, rep(seq_along(per), per))  
  map(h, ~ .x %>% 
            filter(!! extract))

 }

foo(d = 2:4, per = 1:2, extract = age == 2, age = 1:3, prof = c("med", "low", "med"))
#$`1`
#[1] d    age  prof
#<0 rows> (or 0-length row.names)

#$`2`
#  d age prof
#1 3   2  low

Или используя base R

foo <- function(d, per, extract, ...){ ## Add a new argument called `extract`

   extract <- substitute(extract)
   out <- data.frame(d, ...)


   h <- split(out, rep(seq_along(per), per))  
   lapply(h, function(x) subset(x, subset = eval(extract)))

}

foo(d = 2:4, per = 1:2, extract = age == 2, age = 1:3, prof = c("med", "low", "med"))
...