【发布时间】:2016-09-18 02:05:50
【问题描述】:
这在处理 API 时经常出现。
大多数时候,为了进行实际分析,我希望整理我的数据集,但通常这需要针对每种类型的树都有一个解决方案,而不是更通用的解决方案。
我认为拥有一个生成整洁数据的函数会很好(尽管在具有许多不同因子级别的深度嵌套树中存在大量 NA。
我有一个 hackish 解决方案,使用 unlist(..., recursive = FALSE) + 命名约定,
但我想看看这里是否有人有更好的解决方案来整理这些列表结构。
#####################
# Some Test Data
aNestedTree =
list(a = 1,
b = 2,
c = list(
a = list(1:5),
b = 2,
c = list(
a = 1,
d = 3,
e = list())),
d = list(
y = 3,
z = 2
))
############################################################
# Run through the list and rename all list elements,
# We unlist once at time, adding "__" at each unlist step
# until the object is no longer a list
renameVars <- function(lst, sep = '__') {
if(is.list(lst)) {
names(lst) <- paste0(names(lst),sep)
renameVars(unlist(lst, recursive = FALSE),sep = sep)
} else {
lst
}
}
res <- renameVars(aNestedTree)
我们可以检查输出,发现我们有一个奇怪的名字对象, 但是这种疯狂是有办法的。
> res
a________ b________ c__.a____1__ c__.a____2__ c__.a____3__
1 2 1 2 3
c__.a____4__ c__.a____5__ c__.b______ c__.c__.a____ c__.c__.d____
4 5 2 1 3
d__.y______ d__.z______
3 2
现在我把它放在data.table 中,这样我就可以塑造它了。
library(data.table)
dt <- data.table(values = res, name = names(res))
# Use some regex to split that name up, along with data.table's tstrsplit
# function to separate them into as many columns as there are nests
> dt[,paste0('V',seq_along(s <- tstrsplit(dt$name,'[__]+(\\.|)'))) := s]
> dt
values name V1 V2 V3
1: 1 a________ a NA NA
2: 2 b________ b NA NA
3: 1 c__.a____1__ c a 1
4: 2 c__.a____2__ c a 2
5: 3 c__.a____3__ c a 3
6: 4 c__.a____4__ c a 4
7: 5 c__.a____5__ c a 5
8: 2 c__.b______ c b NA
9: 1 c__.c__.a____ c c a
10: 3 c__.c__.d____ c c d
11: 3 d__.y______ d y NA
12: 2 d__.z______ d z NA
然后我可以过滤出我想要的因子组合(或dcast/spread)。 (尽管如果它们存在,我实际上是在最低级别分解表)
我考虑过通过 bind.c 并拉出 do_unlist 以通过 Rcpp 创建一个具有灵活命名约定的函数,但我的 C++ 生锈了,所以我想在我做任何激烈的事情之前我会在这里发帖。
【问题讨论】:
-
你看
data.tree了吗? data.tree introdata.tree application和this question -
现在看,这看起来很有希望