2016-12-07 1 views
3

에 의해 참조 된 것보다 더 큰 요인 목록을 사용하여 xts 개체 x을 신속하고 효율적으로 분할하고 병합하려면 어떻게해야합니까?모든 요인 (누락 된 요인 포함)을 사용하여 분할 된 xts 목록을 병합

이 간단한 예제는 전체 요소 목록 (0으로 채워짐)을 생성하지 않습니다.

a = cbind(value = runif(2), group = c(1,3)) 
x = xts(a, Sys.Date() + 1:nrow(a)) 
do.call(merge, c(split(x$value, x$group), fill = 0)) 

      value.1 value.3 
2016-12-08 0.3403723 0.0000000 
2016-12-09 0.0000000 0.5247683 

내 대안은, 모든 그룹과 연관된 더미 값 추가 분할 및 병합 후

all.groups = 1:5 
x.all.groups = xts(cbind(value = 0, f = all.groups), Sys.Date()-1:length(all.groups)) 
x = rbind(x,x.all.groups) 
as.xts(do.call(merge, c(split(x$value, x$group), fill = 0)))[!(index(x) %in% index(x.all.groups)),] 

      value.1 value.2 value.3 value.4 value.5 
2016-12-08 0.3455855  0 0.00000  0  0 
2016-12-09 0.0000000  0 0.16545  0  0 

다른 해결 조작 split간에 누락 된 그룹들의리스트에 추가하는 것 같이 더미 값을 제거하는 것 및 merge.

그러나 이러한 솔루션은 불필요하게 부피가 큰 것처럼 보입니다. 어떤 제안? split (또는 다른 기능) 및 해당 매개 변수를 활용하는 더 좋은 방법이 있습니까?

답변

1

여기에 tidyverse 해결책이 있습니다. xts 개체는 후드 아래의 행렬이므로 모두 동일한 유형입니다. 따라서 먼저 data.frame으로 변환하고 특정 레벨을 인수에 지정한 다음이 요소에 spread을 지정하십시오.

x %>% as.data.frame %>% 
    mutate(date = row.names(.), 
     group = factor(.$group, levels = 1:5)) %>% 
    spread(group, value, fill = 0, drop = FALSE) 


     date   1 2   3 4 5 
1 2016-12-08 0.2238529 0 0.0000000 0 0 
2 2016-12-09 0.0000000 0 0.6423199 0 0 
1

"대체적이지 않은"대안이 있습니다. :)

# sample data 
set.seed(21) 
x <- xts(cbind(value=runif(5), group=c(1,3,3,1,4)), Sys.Date()-c(2,2,3,1,1)) 
all.groups <- 1:5 

# all unique index values 
unique.index <- unique(index(x)) 
# template object with zero for every unique index value 
xts.template <- xts(rep(0, length(unique.index)), unique.index) 
colnames(xts.template) <- "value" 

# split existing data by group 
s <- split(x$value, x$group) 
# find completely missing groups 
missing.groups <- all.groups[!(all.groups %in% names(s))] 
# add missing groups to list as *named* elements, with all zero values 
s[as.character(missing.groups)] <- 
    replicate(length(missing.groups), xts.template, simplify=FALSE) 

# call merge on all list elements, filling with zeros 
result <- do.call(merge, c(s, fill = 0)) 

# order columns, if you want 
result <- result[,sort(colnames(result))]