【问题标题】:How to change the now deprecated dplyr::funs() which includes an ifelse argument?如何更改包含 ifelse 参数的现已弃用的 dplyr::funs()?
【发布时间】:2019-02-22 19:14:26
【问题描述】:

非常基本,但我认为我并不真正理解变化:

library(dplyr)
library(lubridate)

Lab_import_sql <- Lab_import %>%
    select_if(~sum(!is.na(.)) > 0) %>%
    mutate_if(is.factor, as.character) %>%
    mutate_if(is.character, funs(ifelse(is.character(.), trimws(.),.))) %>%
    mutate_at(.vars = Lab_import %>% select_if(grepl("'",.)) %>% colnames(),
                 .funs = gsub,
                 pattern = "'",
                 replacement = "''") %>%
    mutate_if(is.character, funs(ifelse(is.character(.), paste0("'", ., "'"),.))) %>%
    mutate_if(is.Date, funs(ifelse(is.Date(.), paste0("'", ., "'"),.)))

编辑:

感谢大家的投入,这是可重现的代码和我的解决方案:

library(dplyr)
library(lubridate)

import <- data.frame(Test_Name = "Fir'st Last", 
                     Test_Date = "2019-01-01", 
                     Test_Number = 10)

import_sql <-import %>%
  select_if(~!all(is.na(.))) %>%
  mutate_if(is.factor, as.character) %>%
  mutate_if(is.character, trimws) %>%
  mutate_if(is.character, list(~gsub("'", "''",.))) %>% 
  mutate_if(is.character, list(~paste0("'", ., "'"))) %>%
  mutate_if(is.Date, list(~paste0("'", ., "'")))

【问题讨论】:

  • 鉴于您使用了多少个 dplyr 函数,我认为此时您可以加载 library(dplyr)
  • 由于 dplyr 更新而更新非常旧的代码,我一定会导入它。
  • 文档建议使用 list 和匿名函数的公式语法。喜欢这里mutate_if(is.character, list(~ifelse(is.character(.), trimws(.),.))。没有样本数据就无法测试
  • 不完全清楚为什么在 mutate_if(is.character,...) 内部使用的函数中使用 ifelse(is.character(.),...) ?这不是多余的吗?可重现的例子会很棒,谢谢...
  • 例如mutate_if(is.character, funs(ifelse(is.character(.), trimws(.),.))) 不能只是 mutate_if(is.character,trimws) ... ???

标签: r dplyr


【解决方案1】:

dplyr 0.8.0 开始,documentation 声明我们应该使用list 而不是funs,例如:

之前:

funs(name = f(.))

之后:

list(name = ~f(.))

所以在这里,呼叫funs(ifelse(is.character(.), trimws(.),.)) 可以改为list(~ifelse(is.character(.), trimws(.),.))。这是在tidyverse 中使用匿名函数的公式表示法,其中单边公式(以~ 开头的表达式)被解释为function(x),而x 在函数中的任何位置都由@ 表示987654333@。您仍然可以在list 中使用完整的功能。

注意mutate_if.funs 参数与包装其他函数以传递给.funsfuns() 函数之间的区别;即.funs = gsub 仍然有效。如果您需要将多个函数应用于选定的列或通过将它们作为命名参数传递来命名它们,则只需要funs()。您可以使用 list() 执行所有相同的操作。

您还通过在mutate_if 中添加ifelse 来复制工作;该行可以简化为mutate_if(is.character, trimws),因为如果该列已经是字符,则无需使用ifelse 再次检查它。由于您只应用了一个功能,因此根本不需要funslist

【讨论】:

  • 太好了,这真的清楚了函数在做什么,你能不能看到我最后一点的编辑?谢谢!
  • 这是一个完全不同的问题,因此您可能应该提交一个新问题,包括您想要做什么等详细信息。如所写,该行表示如果列名包含',则将该列转换为在开头与' 和结尾'' 连接的列。
  • 谢谢,我只需要阅读mutate_at() 我认为我不太了解该功能。
  • 所以我有一个场景,我想将所有整数乘以另一列中的值。过去我会使用:mutate_if(is.integer, funs(. * ConvertColumn)) 新方法下的方法是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-05
  • 1970-01-01
  • 2018-10-26
  • 1970-01-01
  • 2021-02-14
相关资源
最近更新 更多