Я пытаюсь переключить свой код с funs () (package dplyr ) на list () , особенно в mutate_if () function.
К сожалению, у меня есть один фрагмент кода, который использует имя столбца в качестве входного параметра. Но при использовании функции 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 ()?
Моя среда:
- Windows 10
- R версия 3.6.1
- dplyr версия 0.8.3
Спасибо
РЕДАКТИРОВАТЬ: решение 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