【问题标题】:mutate(across()) with dplyr and include column name in function call使用 dplyr 进行 mutate(across()) 并在函数调用中包含列名
【发布时间】:2021-01-13 13:13:34
【问题描述】:

我需要对 tibble 的列进行一些计算。我正在使用 mutate(across()) 但我也需要能够传递列名。我有以下测试数据:

mode <- c('PLDV','PLDV','PLDV')
var <- c('PMT','PMT','PMT')
city <- c('City1','City2','City3')
y2015 <- c(1000,2000,3000)
y2020 <- c(1500,2500,3500)
fuel <- c('SI','SI','SI')
scenario <- c('BAU','BAU','BAU')

test1 <- tibble(mode, var, city, y2015, y2020)
test2 <- tibble(scenario, mode, fuel, y2015, y2020)

yrs = c("y2015","y2020")

函数是:

si_calc <- function(x, na.rm=FALSE)(
  pull(test1 %>% filter(mode=="PLDV",var=="PMT") %>%
         select(x) / 1000
  )
)

而函数调用是:

test2 %>% filter(scenario=="BAU", mode=="PLDV", fuel=="SI") %>%
  mutate(across(yrs,si_calc))

我知道x 是列的值,但我还需要传递列名。它似乎更早使用 mutate_at() 工作,但我升级了我的 dplyr 版本,它似乎并没有以同样的方式工作。 pull() 是因为当我在需要将返回的数据类型转换为向量之前让它半工作时,它可以一次正确地应用于多行。

【问题讨论】:

  • 尝试添加此mutate(across(yrs,~si_calc(.))) 某些列不存在于您的数据中!
  • 你为什么要向test2 申请一个从test1 拉出一列的函数?我不明白您要做什么或您的预期输出是什么
  • @Duck 按照您的建议给了我错误:x 不能对不存在的列进行子集化。 x 位置 1000、2000 和 3000 不存在。
  • 您的数据没有在您的函数中使用的列!
  • @RicS test1 包含更新 test2 所需的数据。我无法合并它们,因为行之间的数据不同,我需要对 test1/test2 的不同行执行不同的操作。我是一个 Python 人,但工作必须在 R 中完成,所以我确信有不同的方法可以做到这一点。

标签: r tidyverse dplyr


【解决方案1】:

感谢@Duckmutate(across(yrs,~si_calc(.)))的建议。 dplyr 也有上下文相关的表达式,它给了我我正在寻找的东西 (https://dplyr.tidyverse.org/reference/context.html)。在 cross() 函数中使用 cur_column() 给出当前列名的值。解决办法是:

si_calc <- function(x, na.rm=FALSE)(
  pull(test1 %>% filter(mode=="PLDV",var=="PMT") %>%
         select(curr_column()) / 1000
  )
)

test2 %>% filter(scenario=="BAU", mode=="PLDV", fuel=="SI") %>%
  mutate(across(yrs,si_calc))

【讨论】:

    猜你喜欢
    • 2021-03-01
    • 1970-01-01
    • 2022-06-13
    • 1970-01-01
    • 2014-11-29
    • 2020-08-29
    • 1970-01-01
    • 2021-11-11
    • 2018-11-17
    相关资源
    最近更新 更多