2016-12-07 78 views
3

如何快速高效地拆分和合並xts對象x使用比x引用的更大的因子列表?使用所有因子(包括缺失因子)合併拆分xt的列表

這個簡單的例子不會產生完整的因子列表(填充零)。

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

下面是一個替代方案中, 「非tidyverse」 解決方案。 :)

# 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))]