R strptime не передается по каналу во фрейм данных

#r #dataframe #strptime

#r #фрейм данных #strptime

Вопрос:

 library(dplyr)

names <- c('a','b','c')
dates1 <- c('2020-08-14','2020-08-15','2020-08-16')
dates2 <- c('2019-08-14','2019-08-15','2019-08-16')

df <- data.frame(names, dates1, dates2)
print(colnames(df))

timestamps <- df %>% select(dates1, dates2) %>%
  strptime('%Y-%m-%d')
print(timestamps)
  

Почему это timestamps пара NA s? Как мне заставить его правильно применяться strptime к этим строкам datetime?

Ответ №1:

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

 library(dplyr)
df %>% mutate(across(starts_with('date'), strptime, '%Y-%m-%d'))

#  names     dates1     dates2
#1     a 2020-08-14 2019-08-14
#2     b 2020-08-15 2019-08-15
#3     c 2020-08-16 2019-08-16
  

Поскольку у вас есть только информация о дате в столбцах, вы можете использовать as.Date :

 df %>% mutate(across(starts_with('date'), as.Date))
  

Ответ №2:

Это data.frame с двумя столбцами, и мы могли бы использовать его, as.POSIXct если предполагается преобразовать в DateTime класс путем перебора столбцов с across

 library(dplyr) # >= 1.00
out <- df %>% 
    select(dates1, dates2)  %>%
    mutate(across(everything(), as.POSIXct))
out
#  dates1     dates2
#1 2020-08-14 2019-08-14
#2 2020-08-15 2019-08-15
#3 2020-08-16 2019-08-16
  

Если у нас есть более ранняя версия dplyr , используйте mutate_at или mutate_all

 df %>%
    select(dates1, dates2) %>%
     mutate_all(as.POSIXct)
  

Его также можно использовать с strptime , но остерегайтесь структуры и класса в том виде, в каком они есть POSIXlt

 out2 <- df %>% 
    select(dates1, dates2)  %>%
    mutate(across(everything(), strptime, format = '%Y-%m-%d'))

unclass(out2$dates1)
#$sec
#[1] 0 0 0

#$min
#[1] 0 0 0

#$hour
#[1] 0 0 0

#$mday
#[1] 14 15 16
#...
  

Что касается первоначального вопроса OP о конвейере, он выполняется для одного столбца или вектора

 df %>%
    pull(dates1) %>% 
    strptime(format = '%Y-%m-%d')
#[1] "2020-08-14 CDT" "2020-08-15 CDT" "2020-08-16 CDT"
  

поскольку в документации для ?strptime указано, что входные данные должны быть

x — Объект, подлежащий преобразованию: символьный вектор для strptime, объект, который может быть преобразован в «POSIXlt» для strftime.


Если мы этого не хотим select , используйте модификаторы select

 df %>%       
    mutate(across(-1, as.POSIXct))
# names     dates1     dates2
#1     a 2020-08-14 2019-08-14
#2     b 2020-08-15 2019-08-15
#3     c 2020-08-16 2019-08-16
  

Или, если предполагается преобразовать в Date класс, просто используйте as.Date

 df %>% 
    select(dates1, dates2)  %>%
     mutate(across(everything(), as.Date))
  

ПРИМЕЧАНИЕ: strptime возвращает list и не рекомендуется


Кроме того, другим вариантом является base R

 df[-1] <- lapply(df[-1], strptime, format = '%Y-%m-%d')