使用所有因素(包括缺失因素)合并拆分的 xts 列表
Merge a list of splitted xts using all factors (including missing factors)
如何使用比 x
引用的因素更大的因素列表快速有效地拆分和合并 xts
对象 x
?
这个简单的例子没有产生完整的因素列表(用零填充)。
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
(或其他一些函数)及其参数?
这是一个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
这是另一种 "un-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))]
如何使用比 x
引用的因素更大的因素列表快速有效地拆分和合并 xts
对象 x
?
这个简单的例子没有产生完整的因素列表(用零填充)。
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
(或其他一些函数)及其参数?
这是一个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
这是另一种 "un-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))]