[英]How to apply the same functions to multiple data frames to overwrite input variables using assign(deparse(substitute(df)))? [R]
我有多个具有相同列数的数据框。
iris1 <- iris
iris2 <- iris
然后,我想提取一些特定的列并用具有特定列的那些覆盖原始数据帧。
func <- function(df) {
temp <- df %>%
select("Species",starts_with("Sepal"))
assign(deparse(substitute(df)),temp,envir=.GlobalEnv)
}
如果我将该函数仅应用于一个数据框,则效果很好:
func(iris1)
str(iris1)
'data.frame': 150 obs. of 3 variables:
$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
但是,一旦我尝试将其应用于多个数据帧,它就不起作用:
func(list(iris1,iris2))
Error: Variable context not set
我试图找到解决方案,但大多数建议建议使用lapply
,它以列表格式返回结果。
lapply(list(iris1,iris2),func) -> result
我只想通过函数覆盖数据帧iris1
和iris2
,但是如何?目前我正在通过数据帧运行该函数,但我希望在一个操作中完成。
func(iris1)
func(iris2)
尝试这个:
func <- function(...) {
require(dplyr)
mc <- match.call(expand.dots = FALSE)
lapply(mc$..., function(n) {
assign(deparse(n), get(deparse(n)) %>% select("Species",starts_with("Sepal")), envir = .GlobalEnv)
})
invisible()
}
> str(iris1)
'data.frame': 150 obs. of 5 variables:
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
> str(iris2)
'data.frame': 150 obs. of 5 variables:
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
> func(iris1, iris2)
> str(iris1)
'data.frame': 150 obs. of 3 variables:
$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
> str(iris2)
'data.frame': 150 obs. of 3 variables:
$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
一种方法是使用eval
、 parse
和paste0
在 for 循环内运行命令。 这有效,但并不理想。
for (df in c("iris1", "iris2")) {
eval(parse(text = paste0(df, ' <- select(', df ,', "Species", starts_with("Sepal"))')))
}
这会c("iris1", "iris2")
名称列表并为每个名称运行一个命令,因此列表c("iris1", "iris2")
将运行:
iris1 <- select(iris1, "Species", starts_with("Sepal"))
iris2 <- select(iris2, "Species", starts_with("Sepal"))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.