r - 在 mutate 中将参数传递给 pmap

当与 mutate 一起使用时,我在将参数传递给 purrr::pmap 时遇到问题。 我不明白为什么有些东西有效而有些无效。

我的示例数据:

sdf <- tibble(
  col_id  = c("id1",  "id2", "id3", "id4", "id5", "id6",  "id7",  "id8", "id9", "id10"),
  col_a  = c(0.7,  0.3, 1.4, 0.7, 0.5, 1.1,  0.1,  0.6, 1.7, 0.5),
  col_b  = c(NA, 0.6, 0.2, 0.2, 0.7, 0.2, 0.7,  3.7, 0.7, 0.7),
  col_c  = c(0.3, 0.4,  1.0,  NA,  3.1,  0.2, 0.4,  1.0, 0.1, 0.5))

params = c("col_a", "col_b", "col_c")

然后我想使用 pmap_dbl 在行中执行一些函数。

第一个代码(下方)按预期进行评估。

# code 1
sdf_2 <- sdf %>% 
  select(all_of(params)) %>% 
  mutate(sum_p = pmap_dbl(., sum, na.rm = TRUE))

但是相同的语法不适用于不同的函数:

sdf_2 <- sdf %>% 
  select(all_of(params)) %>% 
  mutate(mean_p = pmap_dbl(., mean, na.rm = TRUE))

Error in mutate(., mean_p = pmap_dbl(., mean, na.rm = TRUE)) : Caused by error in mean.default(): ! argument "x" is missing, with no default

此外,当我尝试将参数直接传递给 sum 函数时 - 而不是通过...它不起作用

sdf_2 <- sdf %>% 
  select(all_of(params)) %>% 
  mutate(sum_p = pmap_dbl(., sum(na.rm = TRUE)))

Error in mutate(., sum_p = pmap_dbl(., sum(na.rm = TRUE))) : Caused by error in pluck(): ! argument "x" is missing, with no default

当水平处理整个数据帧时,将参数传递给 pmap 内部函数的正确方法是什么?

下一个问题: 有什么方法可以传递存储在 params 中的列名,以便仅在它们上执行 pmap 中的功能? select(all_of(params)) 有效,但结果数据框没有 id 列。重新创建很容易,但最好不要完全删除它。

最佳答案

为什么我不能将 mean 解析为 pmap

尝试:

mean(0.7, NA, 0.3, na.rm = TRUE)
sum(0.7, NA, 0.3, na.rm = TRUE)

mean 接受参数 xsum 直接接受 ...(查看文档)。你需要:

mean(c(0.7, NA, 0.3), na.rm = TRUE)

library(dplyr)
library(purrr)

sdf |> 
  mutate(mean_p = pmap_dbl(across(params), ~ mean(c(...), na.rm = TRUE)))

输出:

# A tibble: 10 × 5
   col_id col_a col_b col_c mean_p
   <chr>  <dbl> <dbl> <dbl>  <dbl>
 1 id1      0.7  NA     0.3  0.5  
 2 id2      0.3   0.6   0.4  0.433
 3 id3      1.4   0.2   1    0.867
 4 id4      0.7   0.2  NA    0.45 
 5 id5      0.5   0.7   3.1  1.43 
 6 id6      1.1   0.2   0.2  0.5  
 7 id7      0.1   0.7   0.4  0.4  
 8 id8      0.6   3.7   1    1.77 
 9 id9      1.7   0.7   0.1  0.833
10 id10     0.5   0.7   0.5  0.567

如何在pmap中指定变量?

  1. 使用cur_data()
library(dplyr)
library(purrr)

sdf |>
  mutate(sum_p = pmap_dbl(select(cur_data(), all_of(params)), sum, na.rm = TRUE))
  1. 跨越
library(dplyr)
library(purrr)

sdf |> 
  mutate(sum_p = pmap_dbl(across(params), sum, na.rm = TRUE))
  1. 手册列表
library(dplyr)
library(purrr)

sdf |>
  mutate(sum_p = pmap_dbl(list(col_a, col_b, col_c), sum, na.rm = TRUE))
  1. 使用反引号拼接:
library(dplyr)
library(purrr)
library(rlang)

sdf |>
  mutate(sum_p = pmap_dbl(list(!!!syms(params)), sum, na.rm = TRUE))

输出:

# A tibble: 10 × 5
   col_id col_a col_b col_c sum_p
   <chr>  <dbl> <dbl> <dbl> <dbl>
 1 id1      0.7  NA     0.3   1  
 2 id2      0.3   0.6   0.4   1.3
 3 id3      1.4   0.2   1     2.6
 4 id4      0.7   0.2  NA     0.9
 5 id5      0.5   0.7   3.1   4.3
 6 id6      1.1   0.2   0.2   1.5
 7 id7      0.1   0.7   0.4   1.2
 8 id8      0.6   3.7   1     5.3
 9 id9      1.7   0.7   0.1   2.5
10 id10     0.5   0.7   0.5   1.7

快速方法:将 rowMeans 和 rowSums 与 across 结合使用:

library(dplyr)

sdf |> mutate(mean_p = rowMeans(across(params), na.rm = TRUE))
sdf |> mutate(sum_p = rowSums(across(params), na.rm = TRUE))

更新:添加第四种方式

https://stackoverflow.com/questions/75135231/

相关文章:

python - 无法使用调试暂停 python 进程

python - 查找给定范围内的数字,使给定列表中任何元素的数字的 gcd 始终为 1

fortran - Fortran 能否在逻辑运算中强制遵守参数顺序?

c++ - 是不是 vector.at(vector.size()-1) 比 vector.back

c++ - std::variant 使用整数数组中的元素作为 std::variant 中的目标类

python - 根据条件将新数据从另一个 Dataframe 添加到 Dataframe

c - 尝试复制有关可变参数的 printf 行为

python - Pandas 将 df.count() 结果的最后 n 行求和为一行

vbscript - 当我的 InstallShield 安装程序尝试运行我的 VBS 自定义操作时

perl - Perl 包变量什么时候超出范围?