使用R 3.1.0
a = as.data.frame(do.call(cbind, lapply(1:100, function(x) { c(1,2,3)})))
b = unstack(stack(a))
# Returns FALSE
all(colnames(a) == colnames(b))
stack / unstack上的文档说unstacking应该“反转这个[堆栈]操作”。我错过了什么吗?为什么我需要重新排序b?
的列答案 0 :(得分:2)
stack
(请参阅utils:::stack.data.frame
)函数的最后几行创建一个data.frame
,其中包含两列“值”和“ind”。使用代码
ind = factor(rep.int(names(x), lapply(x, length)))
但是,看看factor
一般如何运作(注意“级别”的顺序):
factor(c(1, 2, 3, 10, 4))
# [1] 1 2 3 10 4
# Levels: 1 2 3 4 10
factor(paste0("A", c(1, 2, 3, 10, 4)))
# [1] A1 A2 A3 A10 A4
# Levels: A1 A10 A2 A3 A4
如果您描述的功能对您的分析很重要,您可以更好地修改stack.data.frame
版本以在保理过程中捕获data.frame
名称的顺序,如下所示:
Stack <- function (x, select, ...)
{
if (!missing(select)) {
nl <- as.list(1L:ncol(x))
names(nl) <- names(x)
vars <- eval(substitute(select), nl, parent.frame())
x <- x[, vars, drop = FALSE]
}
keep <- unlist(lapply(x, is.vector))
if (!sum(keep))
stop("no vector columns were selected")
if (!all(keep))
warning("non-vector columns will be ignored")
x <- x[, keep, drop = FALSE]
data.frame(values = unlist(unname(x)),
# REMOVE THIS --> ind = factor(rep.int(names(x), lapply(x, length))),
# AND ADD THIS:
ind = factor(rep.int(names(x), lapply(x, length)), unique(names(x))),
stringsAsFactors = FALSE)
}
测试,一,二,三......
## Not using identical here because
## the factor levels are different
all.equal(Stack(a), stack(a))
# [1] TRUE
identical(unstack(Stack(a)), a)
# [1] TRUE
答案 1 :(得分:1)
你永远不会让我捍卫R文件......
stack(...)
创建一个包含两列values
和ind
的新数据框。后者具有原始表中的列名,作为因子,按字母顺序排序。 unstack(...)
使用该因子来(重新)创建新数据框的列。因此,应该松散地解释“Unstacking逆转此操作”这一短语......
要获得所需的结果,您需要重新排序系数ind
,如下所示:
a <- as.data.frame(do.call(cbind, lapply(1:100, function(x) { c(1,2,3)})))
c <- stack(a)
c$ind <- factor(c$ind, levels=colnames(a))
d <- unstack(c)
identical(a,d)
# [1] TRUE