R strptime没有管道进入数据框

R strptime not piping into the data frame

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?我如何让它正确地将 strptime 应用于这些日期时间字符串?

它是一个两列 data.frame,我们可以使用 as.POSIXct 如果打算通过使用 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_atmutate_all

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

它也可以与 strptime 一起使用,但要注意结构和 class 因为它是 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 - An object to be converted: a character vector for strptime, an object which can be converted to "POSIXlt" for 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 class,只需使用 as.Date

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

注意:strptime returns list 不推荐


此外,另一种选择是base R

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

您正在将 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))