这是一个显示"动物园"之间明显区别的例子。和" xts"。
library(xts)
mydf = as.data.frame(replicate(6, sample(c(1:10), 10, rep = T)))
myzoo = zoo(mydf, order.by = Sys.Date() + 1:10)
resultzoo = sapply(myzoo, function(x) x+1)
虽然我正在丢失日期(这是已经注释的行为here),但上面的代码运行正常。但是,下面的代码会给出错误
myxts = xts(mydf, order.by = Sys.Date() + 1:10)
resultxts = sapply(myxts, function(x) x+1)
# Error in array(r, dim = d, dimnames = if (!(is.null(n1 <- names(x[[1L]])) & :
# length of 'dimnames' [1] not equal to array extent
我找不到任何解释这种奇怪的行为。任何想法都是受欢迎的。
答案 0 :(得分:3)
我认为你提出了一个非常好的问题。在做出回答之前,我想评论你可以使用
sapply(myzoo, "+", 1)
sapply(myxts, "+", 1)
而不是
sapply(myzoo, function (x) x + 1)
sapply(myxts, function (x) x + 1)
这是因为"+"
已经是一个功能。试试1 + 2
和"+"(1, 2)
。
sapply
分为两个阶段。第一阶段是对lapply
的普通电话;第二阶段是调用simplify2array
以简化结果。您收到的错误消息表明在第二阶段发生了错误。的确,如果我们尝试:
x1 <- lapply(myzoo, "+", 1)
x2 <- lapply(myxts, "+", 1)
我们完全没有错误!
但是,如果我们比较x1
和x2
,我们会看到差异。为了整洁,我将提取第一个列表元素:
x1[[1]]
#2016-09-30 2016-10-01 2016-10-02 2016-10-03 2016-10-04 2016-10-05 2016-10-06
# 3 4 5 7 2 2 4
#2016-10-07 2016-10-08 2016-10-09
# 3 5 3
x2[[1]]
# V1
#2016-09-30 3
#2016-10-01 4
#2016-10-02 5
#2016-10-03 7
#2016-10-04 2
#2016-10-05 2
#2016-10-06 4
#2016-10-07 3
#2016-10-08 5
#2016-10-09 3
啊,对于&#34;动物园&#34;对象,维度被删除所以我们得到一个向量;而对于&#34; xts&#34;对象,维度不会被删除因此我们得到一个列矩阵!
正是由于这个原因,sapply
失败了。默认情况下,sapply
的简化选项为simplify = TRUE
,它总是尝试简化为1D向量或2D矩阵。 x1
,这没问题;但对于x2
,这是不可能的。
如果我们使用较温和的设置:simplify = "array"
,我们会得到适当的行为:
sapply(myzoo, "+", 1, simplify = "array")
给出一个2D数组(即你看到的矩阵); sapply(myxts, "+", 1, simplify = "array")
提供 3D阵列。从这个例子中,我们可以看出sapply
并不总是令人满意的。为什么不使用以下内容:
y1 <- do.call(cbind, x1)
y2 <- do.call(cbind, x2)
# V1 V2 V3 V4 V5 V6
#2016-09-30 3 8 6 4 11 3
#2016-10-01 4 3 9 2 5 7
#2016-10-02 5 7 9 7 7 10
#2016-10-03 7 2 5 3 5 3
#2016-10-04 2 6 7 2 4 5
#2016-10-05 2 2 11 2 4 7
#2016-10-06 4 3 10 10 8 2
#2016-10-07 3 6 4 5 9 4
#2016-10-08 5 4 10 10 3 8
#2016-10-09 3 3 11 8 11 7
他们提供相同的输出,并将日期作为行名称!更重要的是,尊重原始对象类!
class(y1)
# [1] "zoo"
class(y2)
# [1] "xts" "zoo"
<强>后续强>
出于好奇......
*apply
家庭的功能是否等同于您的两步程序(即lapply
+do.call
)?
似乎没有。您可以从?lapply
获取所有这些内容(包括&#34;另请参阅&#34;部分)。如果确实如此,此网站上的用户不会经常lapply
+ do.call
组合。