对堆叠的数据帧进行取消堆叠会以不同的顺序重新堆叠列

时间:2014-04-21 15:51:28

标签: r

使用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?

的列

2 个答案:

答案 0 :(得分:2)

stack(请参阅utils:::stack.data.frame)函数的最后几行创建一个data.frame,其中包含两列“值”和“ind”。使用代码

创建“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(...)创建一个包含两列valuesind的新数据框。后者具有原始表中的列名,作为因子,按字母顺序排序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