很基本,但我认为我不太了解这种变化:
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("'", ., "'")))
答案 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)
再次检查。由于仅应用一个功能,因此完全不需要ifelse
或funs
。