我尝试将代码从 funs()(软件包 dplyr )切换到 list(),尤其是在 mutate_if ()功能。
不幸的是,我有一段代码使用列名作为输入参数。 但是,当使用list()函数时,代码会中断!
此示例代码仅将列的内容替换为列名:
library(tibble)
library(dplyr)
atibble=tribble(~A, ~B,
"A1", "B1",
"A2", "B2")
print(atibble)
## A tibble: 2 x 2
# A B
# <chr> <chr>
#1 A1 B1
#2 A2 B2
atibble %>%
mutate_if(is.character, funs(quo_name(quo(.))))
## A tibble: 2 x 2
# A B
# <chr> <chr>
#1 A B
#2 A B
atibble %>%
mutate_if(is.character, list(~quo_name(quo(.))))
## A tibble: 2 x 2
# A B
# <chr> <chr>
#1 . .
#2 . .
结果不太一样。 :-(
我尝试了很多quo,enquo,rlang :: as_name,..的组合,但没有任何帮助。
如何修复list()语句,使代码显示与funs()相同的结果?
我的环境:
谢谢
编辑: tmfmnk的解决方案有效。我只想在这里显示整个问题。 如果有人找到没有助手功能的解决方案,我将很高兴看到它。 :-)
library(tibble)
library(dplyr)
library(lubridate)
# my original problem involves dates.
btibble=tribble(~A, ~B,
ymd("2019-11-04"), ymd("2019-10-20"),
ymd("2018-02-12"), ymd("2019-02-06"))
# # A tibble: 2 x 2
# A B
# <date> <date>
# 1 2019-11-04 2019-10-20
# 2 2018-02-12 2019-02-06
# And I have a small function that I use.
# It determines the granularity I want for the date column.
getDateUnit <- function(x) {
if (x == 'A') {
return ("month")
}
return("year")
}
# works fine with funs.
btibble %>%
mutate_if(is.Date, funs(floor_date(., getDateUnit(quo_name(quo(.))))))
# Column A is on the first of the month, column B is on the first of the year.
# # A tibble: 2 x 2
# A B
# <date> <date>
# 1 2019-11-01 2019-01-01
# 2 2018-02-01 2019-01-01
# does not work with list because the function call is getDateUnit('.').
# every column will be set to first day of year now
btibble %>%
mutate_if(is.Date, list(~floor_date(., getDateUnit(quo_name(quo(.))))))
# Column A is not formatted by month, but by year.
# # A tibble: 2 x 2
# A B
# <date> <date>
# 1 2019-01-01 2019-01-01
# 2 2018-01-01 2019-01-01
# Throws error
btibble %>%
mutate_if(is.Date, list(function(x) floor_date(x, getDateUnit(quo_name(enquo(x))))))
# Error: `expr` must quote a symbol, scalar, or call
# Call `rlang::last_error()` to see a backtrace.
# The workaround I found was using a helper function that
# does the computing in two steps:
helper_function <- function(x) {
unit = getDateUnit(quo_name(enquo(x)))
return(floor_date(x, unit))
}
# with the helper function both snippets below work.
btibble %>%
mutate_if(is.Date, helper_function)
btibble %>%
mutate_if(is.Date, list(helper_function))
# # A tibble: 2 x 2
# A B
# <date> <date>
# 1 2019-11-01 2019-01-01
# 2 2018-02-01 2019-01-01
答案 0 :(得分:0)
函数.
中不应有list()
:
atibble %>%
mutate_if(is.character, list(function(x) quo_name(enquo(x))))
A B
<chr> <chr>
1 A B
2 A B