潮汐:!!使用 purrr::map 个匿名函数

tidyeval: !! with purrr::map anonymous functions

我想通过跨多个列的条件逻辑创建一个列。这是一个最小的可重现示例。如您所见,双爆炸似乎导致在定义匿名函数之前对 .x 进行评估。关于这个问题的解决方案有什么想法可以让我映射目标列表吗?

library(magrittr)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
df <- data.frame(
  stringsAsFactors = FALSE,
  Well.Position = c("C23", "C24", "D23", "D24"),
  S = c(28.65475574, 28.06971218, 28.04204381, 29.45081936),
  N = c(29.67113762, 29.65467395, 30.00612006, 29.65156431)
)

targets <- c("S", "N")
# works
df %>% 
  dplyr::mutate(PASS =  !!sym(targets[1]) <= 37)
#>   Well.Position        S        N PASS
#> 1           C23 28.65476 29.67114 TRUE
#> 2           C24 28.06971 29.65467 TRUE
#> 3           D23 28.04204 30.00612 TRUE
#> 4           D24 29.45082 29.65156 TRUE
# does not work
df %>% 
  dplyr::mutate(PASS = all(purrr::map_lgl(targets, ~ (!!sym(.x) <= 37))))                
#> Error in is_symbol(x): object '.x' not found

你可以使用if_any-

library(dplyr)

df %>% mutate(PASS = if_any(all_of(targets), ~.x <= 37))

#  Well.Position        S        N PASS
#1           C23 28.65476 29.67114 TRUE
#2           C24 28.06971 29.65467 TRUE
#3           D23 40.00000 30.00612 TRUE
#4           D24 29.45082 29.65156 TRUE

两种方式:

  1. pmap
df %>% 
  dplyr::mutate(PASS = pmap_lgl(select(., !!targets), ~ all(c(...) < 30)))
  1. 按行
df %>% 
  rowwise %>% 
  mutate(PASS = all(c_across(!!targets) < 30))