Используя «глаголы» dplyr, как я могу применить (общую) функцию к столбцу фрейма данных R, если эта функция зависит от нескольких столбцов фрейма данных?
Вот конкретный пример ситуации, с которой я сталкиваюсь. У меня есть такой фрейм данных:
df <- data.frame(
d1 = c('2016-01-30 08:40:00 UTC', '2016-03-06 09:30:00 UTC'),
d2 = c('2016-01-30 16:20:00 UTC', '2016-03-06 13:20:00 UTC'),
tz = c('America/Los_Angeles', 'America/Chicago'), stringsAsFactors = FALSE)
Я хочу преобразовать время UTC в местное время, чтобы получить такой кадр данных:
d1 d2 tz
1 2016-01-30 00:40:00 2016-01-30 08:20:00 America/Los_Angeles
2 2016-03-06 03:30:00 2016-03-06 07:20:00 America/Chicago
Для этого я хотел бы применить следующую функцию, которая преобразует время UTC в местное время с помощью библиотеки lubridate, к столбцам даты:
getLocTime <- function(d, tz) {
as.character(with_tz(ymd_hms(d), tz))
}
Используя dplyr, кажется, что преобразование
df %>% mutate(d1 = getLocTime(d1, tz), d2 = getLocTime(d2, tz))
должен сделать трюк. Однако это не удается с жалобой Error in eval(expr, envir, enclos): invalid 'tz' value
.
Единственный способ, которым мне удалось выполнить преобразование в местное время, - это довольно неуклюжее назначение
df[c('d1', 'd2')] <- lapply(c('d1', 'd2'),
function(x) unlist(Map(getLocTime, df[[x]], df$tz)))
Существует ли естественный способ выполнить это преобразование с помощью идиом dplyr?
getLocTime(c("2016-01-30 08:40:00 UTC", "2016-03-06 09:30:00 UTC"), c("America/Los_Angeles", "America/Chicago"))
для 1-гоmutate
, что не работает. Вы можете векторизовать свою функцию, например.vgetLocTime <- Vectorize(getLocTime, c("d", "tz"))
. - person lukeA   schedule 09.05.2016Vectorize
вашей функции, как предложил @lukeA, вы также можете использоватьmutate_each
, чтобы упростить изменение нескольких столбцов:df %>% mutate_each(funs(getLocTime(., tz)), matches("d"))
- person eipi10   schedule 09.05.2016mutate_each
— спасибо! Страница справки дляmutate_each
, похоже, не упоминаетmatches
. Какова точная форма аргументовmatches
? Может ли быть несколько совпадений, то есть будет лиmatches("d1", "d2")
эквивалентным совпадением? - person egnha   schedule 09.05.2016matches
задокументирован какselect
, который является глаголом для выбора столбцов фрейма данных.matches
позволяет выбирать столбцы с помощью регулярного выражения. В этом случае d будет соответствовать любому столбцу, имя которого содержит d. При необходимости отрегулируйте имена ваших реальных столбцов или вы можете предпочесть использовать одну из других вспомогательных функций, описанных в разделеselect
, для выбора столбцов фрейма данных. - person eipi10   schedule 09.05.2016matches
будет работать только допустимое регулярное выражение. Вы можете использоватьmatches("d[12]")
(эквивалентноmatches("d1|d2")
, но короче), но только"d"
будет работать, если только вам не нужно исключить другие столбцы, содержащие d и другие символы. Например, если вам нужны только столбцы, начинающиеся с d и заканчивающиеся цифрами от 1 до 5, вы можете сделатьmatches("^d.*[1-5]$")
. - person eipi10   schedule 09.05.2016