R语言mutate中pmap_df作用于全数据框而非对应行的问题
问题说明
现有数据框每一行存储待传入目标函数的参数,目标函数执行后会返回多行记录的数据框。预期参照mutate搭配pmap_dbl新增结果列的用法,调用pmap_df将入参与对应计算结果整合到同一数据框中。
使用如下代码运行后,结果列存储的嵌套数据每行都包含全量计算结果,未和当前行入参做匹配:
library(tidyr) example_function <- function(data, string, ...){ word_one <- paste(data$word_one, string) word_two <- paste(data$word_two, string) output <- data_frame(result_words = c(word_one, word_two)) } fake_data <- tibble(group_id = rep(c(1, 2), each = 3), word_one = c("hello", "goodbye", "today", "apple", "banana", "coconut"), word_two = c("my", "name", "is", "ellie", "good", "morning")) test <- fake_data %>% group_by(group_id) %>% nest() %>% mutate(string = "not working") %>% mutate(final_output = list(purrr::pmap_df(.l = ., .f = example_function)))
运行后得到的错误输出结构如下:
Rows: 2 Columns: 4 Groups: group_id [2] $ group_id <dbl> 1, 2 $ data <list> [<tbl_df[3 x 2]>], [<tbl_df[3 … $ string <chr> "not working", "not working" $ final_output <list> [<tbl_df[12 x 1]>], [<tbl_df[…
预期效果:final_output列每个元素存储的数据框仅包含6行结果,和嵌套data列的输入一一对应。
问题原因
代码中pmap_df的传入参数为.,即nest之后整个2行的完整数据框。pmap会遍历传入列表/数据框的所有元素(即所有分组行)执行函数,最终拼接得到全量2组共12行的结果,再重复赋值给每一行的final_output列,因此出现每行都存储全量结果的问题。
实现方案
该需求可直接实现,核心逻辑:逐行传入当前行对应的参数给目标函数,而非传入整个完整数据框。
由于每行仅需传入data、string两个参数,可直接使用map2逐行映射,修正后代码如下:
test <- fake_data %>% group_by(group_id) %>% nest() %>% mutate(string = "not working") %>% mutate(final_output = purrr::map2(.x = data, .y = string, .f = example_function))
如果需要使用pmap适配更多参数场景,可显式指定逐行传入的参数列,写法如下:
test <- fake_data %>% group_by(group_id) %>% nest() %>% mutate(string = "not working") %>% mutate(final_output = purrr::pmap(.l = list(data = data, string = string), .f = example_function))
运行后查看结果,final_output列每个元素为对应分组生成的6行1列数据框,完全匹配预期。
内容的提问来源于stack exchange,提问作者Emily
相关产品推荐
相关产品推荐

