为什么sapply不能使用lubridate的parse_date_time而lapply却不使用?

Cap*_*ous 4 r lapply sapply lubridate

给定:一个简单的4x2数据帧,其中填充了字符类型的数据

目标:相同的数据框,但所有值均替换为对它们应用以下lubridate函数调用的结果: parse_date_time(df, orders = c ("ymd_hms", "mdy_hms"), tz = "ETZ")

似乎使用lapply可以正常工作。使用sapply时,parse_date_time函数返回奇怪的大整数。

数据如下:

df <- as.data.frame(stringsAsFactors = FALSE, matrix(c("2014-01-13 12:08:02", "2014-01-13 12:19:46", "2014-01-14 09:59:09", "2014-01-14 10:05:09", "6-18-2016 17:43:42", "6-18-2016 18:06:59", "6-27-2016 12:16:47", "6-27-2016 12:29:05"), nrow = 4, ncol = 2, byrow = TRUE))

colnames(df) <- c("starttime", "stoptime")

这是sapply调用:

df2 <- sapply(df, FUN = function(column) { parse_date_time(column, orders = c("ymd_hms", "mdy_hms"), tz = "ETZ") })

和讨厌的电话:

df2 <- lapply(df, FUN = function(column) { parse_date_time(column, orders = c("ymd_hms", "mdy_hms"), tz = "ETZ") })

我知道sapply返回它可以实现的最简单的数据结构,而lapply返回一个列表。如果工作得很顺利,那么后面将是df2 <- data.frame(df2)这样,这样我将具有“目标”中所述的所需数据帧(请注意,我确实使用成功的lapply返回列表来完成此操作)。

我的问题是,为什么parse_date_time函数在lapply中表现出预期,但在sapply中表现却不如预期?作为参考,以下分别是lapply和sapply调用的示例输出:

2016-06-27 12:29:05

1467030545

akr*_*run 5

原因是sapply默认情况下具有,simplify = TRUE并且当list元素的长度或尺寸相同时,它会简化为a vectormatrix。在内部,日期时间类存储为数字,

typeof(parse_date_time(df$starttime, orders = c("ymd_hms", "mdy_hms"), tz = "ETZ"))
#[1] "double"
Run Code Online (Sandbox Code Playgroud)

class“ POSIXct”

class(parse_date_time(df$starttime, orders = c("ymd_hms", "mdy_hms"), tz = "ETZ"))
#[1] "POSIXct" "POSIXt"  
Run Code Online (Sandbox Code Playgroud)

因此在进行matrix转换时会强制转换,而在转换时list会保留class格式。

如果我们对感兴趣data.frame,则我们创建'df'的副本并用于[]获取与'df'相同的结构

df2 <- df
df2[] <-  lapply(df, FUN = function(column) {
     parse_date_time(column, orders = c("ymd_hms", "mdy_hms"), tz = "ETZ")
   })

df2
#           starttime            stoptime
#1 2014-01-13 12:08:02 2014-01-13 12:19:46
#2 2014-01-14 09:59:09 2014-01-14 10:05:09
#3 2016-06-18 17:43:42 2016-06-18 18:06:59
#4 2016-06-27 12:16:47 2016-06-27 12:29:05
Run Code Online (Sandbox Code Playgroud)