Преобразование выбранных столбцов из POSIXct в Date с определенным форматом с помощью функции apply - PullRequest
0 голосов
/ 27 августа 2018

Иногда я читаю данные из Microsoft Excel в R. В Excel переменные даты форматируются правильно (например, 31 декабря 2017 года).После чтения в R та же переменная даты преобразуется в другой формат (например, 2017-12-31).

Пример моего фрейма данных (после чтения в R) выглядит следующим образом:

df <- structure(list(ID = c("001", "002", "003", "004", "005"), 
           t1_date = structure(c(1490227200, 1508198400, 1511395200, 1527292800, 1485216000), 
                                         class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
           t2_date = structure(c(1524009600, NA, NA, NA, 1523232000), 
                                         class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
           t3_date = c(NA, NA, NA, NA, NA), 
           t4_date = c(NA, NA, NA, NA, NA), 
           t5_date = c(NA, NA, NA, NA, NA)), 
      .Names = c("ID", "t1_date", "t2_date", "t3_date", "t4_date", "t5_date"), 
      row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"))

Используя в качестве примера переменную t1_date, я могу индивидуально преобразовать каждый столбец даты из класса POSIXct (который R выбирает для меня) в класс Date, а затем изменить формат, используя следующий код:

df$t1_date <- as.Date(df$t1_date)
df$t1_date <- format(df$t1_date, "%d-%b-%Y")

Однако у меня есть много столбцов даты, и они могут не быть смежными друг с другом в фрейме данных.

Обычно для решения таких проблем я использую функции which и applyчтобы выбрать соответствующие столбцы и применить к ним функцию:

df[, which(colnames(df) == "t1_date"):
 which(colnames(df) == "t5_date")] <- 
  apply(df[, which(colnames(df) == "t1_date"):
         which(colnames(df) == "t5_date")], 2, function(x) as.Date(x, format = "%d-%b-%Y"))

Приведенный выше код привел к появлению NA во всех столбцах даты, и я не уверен, почему.Даже если я не форсирую изменение формата, но преобразую столбцы даты из класса POSIXct в класс Date, код все равно не работает (см. Ниже):

df[, which(colnames(df) == "t1_date"):
 which(colnames(df) == "t5_date")] <- 
  apply(df[, which(colnames(df) == "t1_date"):
         which(colnames(df) == "t5_date")], 2, as.Date)

Мой желаемый результат заключается впреобразовать даты в формат ДД-МММ-ГГГГ (например, 31 декабря 2017 года).

Помощь приветствуется.Спасибо!

1 Ответ

0 голосов
/ 27 августа 2018

Мы выбираем диапазон столбцов, которые мы хотим отформатировать, а затем конвертируем их в даты, используя as.Date, а затем format, исходя из наших требований.

start_col <- which(colnames(df) == "t1_date")
end_col <-  which(colnames(df) == "t5_date")
df[start_col:end_col] <- lapply(df[start_col:end_col], 
                        function(x) format(as.Date(x), "%d-%b-%Y"))


df
# A tibble: 5 x 6
#  ID    t1_date     t2_date     t3_date t4_date t5_date
#  <chr> <chr>       <chr>       <chr>   <chr>   <chr>  
#1 001   23-Mar-2017 18-Apr-2018 NA      NA      NA     
#2 002   17-Oct-2017 NA          NA      NA      NA     
#3 003   23-Nov-2017 NA          NA      NA      NA     
#4 004   26-May-2018 NA          NA      NA      NA     
#5 005   24-Jan-2017 09-Apr-2018 NA      NA      NA    

То же самое можно сделать с помощью dplyr, mutate_at

library(dplyr)
df %>%
  mutate_at(vars("t1_date":"t5_date"), funs(format(as.Date(.), "%d-%b-%Y")))


#  ID    t1_date     t2_date     t3_date t4_date t5_date
#  <chr> <chr>       <chr>       <chr>   <chr>   <chr>  
#1 001   23-Mar-2017 18-Apr-2018 NA      NA      NA     
#2 002   17-Oct-2017 NA          NA      NA      NA     
#3 003   23-Nov-2017 NA          NA      NA      NA     
#4 004   26-May-2018 NA          NA      NA      NA     
#5 005   24-Jan-2017 09-Apr-2018 NA      NA      NA  
...