应用 + lubridate returns 数字
Apply + lubridate returns numeric
我有一个看起来像这样的数据集
birds[,1:3]
Source: local data frame [15 x 3]
year month day
1 2015 5 13
2 2015 5 14
3 2015 5 15
4 2015 5 16
5 2015 5 17
6 2014 5 28
7 2014 5 29
8 2014 5 30
9 2014 5 31
10 2014 6 1
11 2013 5 8
12 2013 5 9
13 2013 5 10
14 2013 5 11
15 2013 5 12
我想做的是将这些列合并为一个 "date" 列,所以我想我可以将它们粘贴在一起并传递给 lubridate。
这个有效:
ymd(paste(birds[1,1], birds[1,2], birds[1,3], sep="-"))
[1] "2015-05-13 UTC"
但是当我尝试使用 apply 对每一行执行此操作时,我得到了这个:
apply(birds[,c("year","month","day")], 1,
function(x) ymd(paste(x[1], x[2], x[3], sep="-")))
[1] 1431475200 1431561600 1431648000 1431734400 1431820800 1401235200 1401321600 1401408000 1401494400
[10] 1401580800 1367971200 1368057600 1368144000 1368230400 1368316800
为什么会发生这种情况,我该如何解决?
我们不需要 apply
和 MARGIN=1
。相反,我们可以通过 with(birds, paste(year, month, day, sep="-"))
paste
列并将其用 as.Date
包裹起来以转换为 'Date' class。 ymd
的输出是POSIXct
class,在apply
里面,会被强制转换成'numeric'的形式。
library(lubridate)
library(dplyr)
mutate(birds, date=ymd(paste(year, month, day)))
或者我们可以使用 tidyr
中的 unite
然后转换为 POSIXct
class
library(tidyr)
unite(birds, date, year:day, sep="-") %>%
mutate(date=ymd(date))
或使用 base R
中的 do.call
和 ymd
birds$date <- ymd(do.call(paste, birds))
或者您可以使用 base R
中的 as.Date
as.Date(do.call(paste, c(birds,sep="-")))
修复您使用 apply
获得的输出
res <- apply(birds[,c("year","month","day")], 1,
function(x) ymd(paste(x[1], x[2], x[3], sep="-")))
unname(as.POSIXct(res, origin='1970-01-01',tz='UTC'))
#[1] "2015-05-13 UTC" "2015-05-14 UTC" "2015-05-15 UTC" "2015-05-16 UTC"
#[5] "2015-05-17 UTC" "2014-05-28 UTC" "2014-05-29 UTC" "2014-05-30 UTC"
#[9] "2014-05-31 UTC" "2014-06-01 UTC" "2013-05-08 UTC" "2013-05-09 UTC"
#[13] "2013-05-10 UTC" "2013-05-11 UTC" "2013-05-12 UTC"
数据
birds <- structure(list(year = c(2015L, 2015L, 2015L, 2015L, 2015L,
2014L,
2014L, 2014L, 2014L, 2014L, 2013L, 2013L, 2013L, 2013L, 2013L
), month = c(5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 5L, 5L,
5L, 5L, 5L), day = c(13L, 14L, 15L, 16L, 17L, 28L, 29L, 30L,
31L, 1L, 8L, 9L, 10L, 11L, 12L)), .Names = c("year", "month",
"day"), class = "data.frame", row.names = c("1", "2", "3", "4",
"5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"))
我有一个看起来像这样的数据集
birds[,1:3]
Source: local data frame [15 x 3]
year month day
1 2015 5 13
2 2015 5 14
3 2015 5 15
4 2015 5 16
5 2015 5 17
6 2014 5 28
7 2014 5 29
8 2014 5 30
9 2014 5 31
10 2014 6 1
11 2013 5 8
12 2013 5 9
13 2013 5 10
14 2013 5 11
15 2013 5 12
我想做的是将这些列合并为一个 "date" 列,所以我想我可以将它们粘贴在一起并传递给 lubridate。
这个有效:
ymd(paste(birds[1,1], birds[1,2], birds[1,3], sep="-"))
[1] "2015-05-13 UTC"
但是当我尝试使用 apply 对每一行执行此操作时,我得到了这个:
apply(birds[,c("year","month","day")], 1,
function(x) ymd(paste(x[1], x[2], x[3], sep="-")))
[1] 1431475200 1431561600 1431648000 1431734400 1431820800 1401235200 1401321600 1401408000 1401494400
[10] 1401580800 1367971200 1368057600 1368144000 1368230400 1368316800
为什么会发生这种情况,我该如何解决?
我们不需要 apply
和 MARGIN=1
。相反,我们可以通过 with(birds, paste(year, month, day, sep="-"))
paste
列并将其用 as.Date
包裹起来以转换为 'Date' class。 ymd
的输出是POSIXct
class,在apply
里面,会被强制转换成'numeric'的形式。
library(lubridate)
library(dplyr)
mutate(birds, date=ymd(paste(year, month, day)))
或者我们可以使用 tidyr
中的 unite
然后转换为 POSIXct
class
library(tidyr)
unite(birds, date, year:day, sep="-") %>%
mutate(date=ymd(date))
或使用 base R
中的 do.call
和 ymd
birds$date <- ymd(do.call(paste, birds))
或者您可以使用 base R
as.Date
as.Date(do.call(paste, c(birds,sep="-")))
修复您使用 apply
res <- apply(birds[,c("year","month","day")], 1,
function(x) ymd(paste(x[1], x[2], x[3], sep="-")))
unname(as.POSIXct(res, origin='1970-01-01',tz='UTC'))
#[1] "2015-05-13 UTC" "2015-05-14 UTC" "2015-05-15 UTC" "2015-05-16 UTC"
#[5] "2015-05-17 UTC" "2014-05-28 UTC" "2014-05-29 UTC" "2014-05-30 UTC"
#[9] "2014-05-31 UTC" "2014-06-01 UTC" "2013-05-08 UTC" "2013-05-09 UTC"
#[13] "2013-05-10 UTC" "2013-05-11 UTC" "2013-05-12 UTC"
数据
birds <- structure(list(year = c(2015L, 2015L, 2015L, 2015L, 2015L,
2014L,
2014L, 2014L, 2014L, 2014L, 2013L, 2013L, 2013L, 2013L, 2013L
), month = c(5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 5L, 5L,
5L, 5L, 5L), day = c(13L, 14L, 15L, 16L, 17L, 28L, 29L, 30L,
31L, 1L, 8L, 9L, 10L, 11L, 12L)), .Names = c("year", "month",
"day"), class = "data.frame", row.names = c("1", "2", "3", "4",
"5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"))