如何更改现已弃用的dplyr :: funs()(其中包含ifelse参数)?

时间:2019-02-22 19:14:26

标签: r dplyr

很基本,但我认为我不太了解这种变化:

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("'", ., "'"),.)))

编辑:

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

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("'", ., "'")))

1 个答案:

答案 0 :(得分:11)

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在哪里函数中的go用.表示。您仍然可以在list中使用完整功能。

请注意.funs的{​​{1}}参数和mutate_if函数之间的区别,后者包装了其他函数以传递给funs();即.funs仍然有效。仅在需要将多个函数应用于选定的列或通过将它们作为命名参数传递来命名它们时,才需要.funs = gsub。您可以使用funs()做所有相同的事情。

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