2017-10-04 44 views
2

我对R,一个chron对象和sapply函数有问题。我改变了默认原点:用chron和sapply在R上的可能的错误

chron_start <- chron("01/01/2010", "00:30:00",origin.=c(month=1, day=1, year=1900)) 
ch <- chron_start+(0:(365*24-1))/24 

现在,如果我跑:

> sprintf("%s", years(ch[1])) 
[1] "2010" 

但是,如果我有sapply反复运行它,我得到:

> anios <- sapply(ch, function(x){sprintf("%s", years(x))}) 
> anios[1] 
[1] "2080" 

所以它得到70年提前,这是我的起源(1900年)和默认起源(1970年)之间的差异。

我想问你是否发生这种情况,为了发送错误报告,或者如果有解释这种行为,以及如何解决它。

在此先感谢!

P.S .:我的R版本是“R版本3.4.2(2017-09-28)”,运行在GNU/Linux openSUSE Leap 42.2 64位上。 Chron软件包版本是2.3-45

+0

我在R 3.4.1上得到了这个行为在Windows 7与Chron 2.3-50。 –

+1

'sapply'(像'lapply')应该作用于'list'对象。如果不是,则调用'as.list'。看到'as.list(ch)'将失去任何关于原点的迹象。所以'年代'将会采用标准的POSIX起源(1970年1月1日)。另外,在你的例子中,你可以简单地尝试'sprintf(“%s”,years(ch))' – nicola

+0

实际上我正在做的比这个有点复杂,所以'sprintf(“%s”,years(ch)) '不适合我。我刚刚通过做循环来解决这个问题 –

回答

1

我会尝试而不是与chron一起使用非默认原点或至少将它们尽可能快地转换为默认原点。

这里我们创建ch0,它代表与ch相同的日期时间,但是具有默认原点。 Chron软件包具有origin函数(以及origin<-函数)来帮助完成此操作,但不会导出,因此我们必须使用chron:::作为前缀。

ch0 <- chron(ch, origin = chron::origin(chron(0))) 

# now we get the expected years 
anios <- sapply(ch0, function(x){sprintf("%s", years(x))}) 
head(anios) 
## [1] "2010" "2010" "2010" "2010" "2010" "2010" 

注:为ch0表达另一种上面会:

format(years(ch0)) 

,没有我们做的不是sapply:

ch0 <- ch 
chron:::origin(ch0) <- chron:::origin(chron(0)) 

另外,sapply可以替换为甚至需要ch0所以这个工程:

format(years(ch)) 

更新:作为克罗恩氏“51年2月3日”(只上传到CRAN)origin的出口,以便代码的第一行之上不再需要chron:::

ch0 <- chron(ch, origin = origin(chron(0))) 

更新2:已更新注意。

+0

非常感谢您的建议。我不确定如何将一个chron对象“转换”为默认原点。这是有帮助的! –