11

是否可以在内部的 lambda 函数中引用列across()

df <- tibble(age = c(12, 45), sex = c('f', 'f'))
allowed_values <- list(age = 18:100, sex = c("f", "m"))

df %>%
  mutate(across(c(age, sex),
                c(valid = ~ .x %in% allowed_values[[COLNAME]])))

我刚刚遇到了这个问题,其中 OP 询问基于允许值列表验证数据框中的列。

dplyr刚刚获得across(),这似乎是一个自然的选择,但我们需要列名来查找允许的值。

我能想到的最好的方法是调用imap_dfr,但是集成到分析管道中更加麻烦,因为需要将结果与原始数据帧重新组合。

4

2 回答 2

9

答案是肯定的,可以参考dplyr's中的列名across。你需要使用cur_column(). 你原来的答案是如此接近!cur_column()在您想要列名的位置插入您的解决方案:

library(tidyverse)

df <- tibble(age = c(12, 45), sex = c('f', 'f'))
allowed_values <- list(age = 18:100, sex = c("f", "m"))

df %>%
  mutate(across(c(age, sex),
                c(valid = ~ .x %in% allowed_values[[cur_column()]])
                )
         )

参考:https ://dplyr.tidyverse.org/articles/colwise.html#current-column

于 2020-12-10T11:51:22.747 回答
2

我认为您此时可能要求太多across(但这可能会刺激额外的发展,所以也许有一天它会按照您的建议方式工作)。

我认为imappurrr 包中的功能可能会给你你想要的东西:

> df <- tibble(age = c(12, 45), sex = c('f', 'f'))
> allowed_values <- list(age = 18:100, sex = c("f", "m"))
> 
> df %>% imap( ~ .x %in% allowed_values[[.y]])
$age
[1] FALSE  TRUE

$sex
[1] TRUE TRUE

> df %>% imap_dfc( ~ .x %in% allowed_values[[.y]])
# A tibble: 2 x 2
  age   sex  
  <lgl> <lgl>
1 FALSE TRUE 
2 TRUE  TRUE 

如果您想要一个具有组合有效性的列,那么您可以通过以下方式传递结果reduce

> df %>% imap( ~ .x %in% allowed_values[[.y]]) %>%
+   reduce(`&`)
[1] FALSE  TRUE

然后可以将其作为新列添加到原始数据中,或者仅用于对数据进行子集化。我对 tidyverse 不够专业,还不知道是否可以将其结合起来mutate直接添加列。

于 2020-06-02T18:14:35.523 回答