2016-09-29 5 views
2

다음은 "동물원"과 "xts"의 명확한 차이점을 보여주는 예입니다. 나는 (이 이미 here 주석 행동이다) 날짜를 손실하고 있지만``sapply`는 "zoo"객체에는 성공했지만 "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) 

는 위의 코드는 잘 작동합니다. 그러나 아래 코드는 오류가 발생합니다.

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

'sapply'는 첫 번째 인수 인'X'에 대한리스트와 함께 호출되도록되어 있습니다. 그리고 'X'가 하나가 아니면 'X'가 목록에 강제 적용됩니다. 동물원/xts 객체에서'sapply'를 호출하는 더 좋은 대안은'apply (X, 2, FUN)'을 사용하여 열을 반복하는 것입니다. –

답변

3

나는 아주 좋은 질문을 제기했다고 생각합니다. 내 대답을하기 전에, 당신이 "+" 이미 기능이기 때문이다

sapply(myzoo, "+", 1) 
sapply(myxts, "+", 1) 

대신

sapply(myzoo, function (x) x + 1) 
sapply(myxts, function (x) x + 1) 

으로 사용할 수 있음을 언급하고 싶습니다. 1 + 2"+"(1, 2)을 시도하십시오.


sapply은 2 단계를 취한다. 첫 번째 단계는 lapply에 대한 일반적인 호출입니다. 두 번째 단계는 결과 단순화를 위해 simplify2array을 호출하는 것입니다. 오류 메시지는 두 번째 단계에서 잘못된 것이 있음을 알립니다. 실제로 시도한 경우 :

x1 <- lapply(myzoo, "+", 1) 
x2 <- lapply(myxts, "+", 1) 

전혀 오류가 발생하지 않습니다.

그러나 x1x2을 비교하면 차이가 있습니다. 깔끔함을 위해 첫 번째 목록 요소를 추출합니다.

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 

아, "동물원"개체의 경우 벡터가 생성되도록 치수가 삭제됩니다. 반면 "xts"객체의 경우 차원이 삭제되지 않으므로 단일 열 행렬을 얻습니다!

정확히 sapply이 실패하는 이유입니다. 기본적으로 sapply의 단순화 옵션은 항상 1D 벡터 또는 2D 행렬로 단순화하려고 시도하는 simplify = TRUE입니다. x1의 경우 이것은 문제가되지 않습니다. 그러나 x2의 경우 이는 불가능합니다. 우리는 온화한 설정을 사용하는 경우

:

  1. sapply(myzoo, "+", 1, simplify = "array")는 2 차원 배열을 제공합니다 (즉, 당신이 볼 행렬) : simplify = "array"을, 우리는 적절한 행동을 얻을 것이다
  2. sapply(myxts, "+", 1, simplify = "array")3D 배열을 제공합니다.
  3. 이 예에서

, 우리는 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 ("관련 정보"부분 포함)에서 모두 가져올 수 있습니다. 실제로 존재한다면,이 사이트의 사람들은 lapply + do.call 조합을 그렇게 자주하지 않을 것입니다.

+0

귀하의 자세한 답변에 많은 감사드립니다. 정말 도움이되었습니다. 호기심에서 .... "적용"가족이 두 단계 절차 (즉, lapply + do.call)에 해당하는 기능이 있습니까? –