我有一个函数,我传递三个变量(列名)和一个数据帧,并将结果放入带有 map_dfr
的数据帧中,效果很好。
library(tidyverse)
iris_median<-function(df, col){
df%>%
summarise(Median=median(.data[[col]], na.rm=TRUE))%>%
mutate(field=as.character(!!col))
}
median_df <- map_dfr(c("Sepal.Length","Sepal.Width",
"Petal.Length"), .f=iris_median,
df= iris)
当我尝试将多个数据帧传递到此函数时,如下所示:
iris1 <- iris [1:50,]
iris2 <- iris [51:100,]
median_df <- map_dfr("Sepal.Length", .f=iris_median,
df= c(iris1, iris2))
我收到错误消息:没有适用于“summarise”的方法应用于“list”类的对象
我不明白为什么它不只是迭代两个不同的数据帧并为每个数据帧进行计算。
有人可以修改代码吗?
最佳答案
map_dfr
迭代第一个参数(.x
参数)中的项目。它不会迭代通过 ...
传递的附加参数。
由于 map_
函数只是循环的包装器,因此您的调用
map_dfr("Sepal.Length", .f = iris_median, df = c(iris1, iris2))
调用iris_median
函数一次(因为第一个参数的长度为1),并立即将整个列表传递给df
参数。这相当于
iris_median(df = c(iris1, iris2), col = "Sepal.Length")
正是这个调用导致了您的错误,因为您正在尝试总结
一个列表
。
要让 map_dfr
处理数据框列表,您需要将该列表作为第一个 (.x
) 参数传递,并将单个列名称传递为一个附加参数:
map_dfr(.x = list(iris1, iris2),
.f = iris_median,
col = "Sepal.Length")
#> Median field
#> 1 5.0 Sepal.Length
#> 2 5.9 Sepal.Length
如果您想遍历数据框列表和列名向量,您需要map2_dfr
,它会遍历前两个参数。
map2_dfr(.x = list(iris1, iris2),
.y = c("Sepal.Length", "Petal.Width"),
.f = iris_median)
#> Median field
#> 1 5.0 Sepal.Length
#> 2 1.3 Petal.Width
更新
请注意,map2_dfr
并行迭代 .x
和 .y
参数。如果您想要数据框和列名称的所有可能组合,则需要首先通过 cross
传递数据框和列名称。
df_list <- list(iris1, iris2)
col_vec <- c("Sepal.Length", "Sepal.Width")
cross(.l = list(df_list, col_vec)) %>%
map_dfr(~ iris_median(.x[[1]], .x[[2]]))
#> Median field
#> 1 5.0 Sepal.Length
#> 2 5.9 Sepal.Length
#> 3 3.4 Sepal.Width
#> 4 2.8 Sepal.Width
关于r - 将多个数据帧传递到函数中以使用map_dfr生成数据帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76706277/