table() 函数是否有通用的反函数?

9
我知道一点编程可以将定长频数表格(例如table()返回的表格)转换回观测数据。因此,目标是将这样一个频数表格转换为...
(flower.freqs <- with(iris,table(Petal=cut(Petal.Width,2),Species)))
          Species
Petal          setosa versicolor virginica
  (0.0976,1.3]     50         28         0
  (1.3,2.5]         0         22        50

将输入矩阵中的数字求和,然后将结果转换为行数对应的data.frame(),单元格值从输入维度中获取。
     Petal Species
1 (0.0976,1.3]  setosa
2 (0.0976,1.3]  setosa
3 (0.0976,1.3]  setosa
# ... (150 rows) ...

通过一些调整,我建立了一个粗略的原型,也能处理更高维度的输入:

tableinv <- untable <- function(x) {
    stopifnot(is.table(x))
    obs <- as.data.frame(x)[rep(1:prod(dim(x)),c(x)),-length(dim(x))-1]
    rownames(obs) <- NULL; obs
}

> head(tableinv(flower.freqs)); dim(tableinv(flower.freqs))
     Petal Species
1 (0.0976,1.3]  setosa
2 (0.0976,1.3]  setosa
3 (0.0976,1.3]  setosa
4 (0.0976,1.3]  setosa
5 (0.0976,1.3]  setosa
6 (0.0976,1.3]  setosa
[1] 150   2
> head(tableinv(Titanic)); nrow(tableinv(Titanic))==sum(Titanic)
  Class  Sex   Age Survived
1   3rd Male Child       No
2   3rd Male Child       No
3   3rd Male Child       No
4   3rd Male Child       No
5   3rd Male Child       No
6   3rd Male Child       No
[1] TRUE

我显然为这个拼凑重建多属性数据框架(如Titanic)从高维频率表感到自豪,但是是否有一个已建立的(内置,经过实战测试的)通用逆向table()的方法,最好不依赖于特定库,知道如何处理未标记的维度,优化以使其不会在庞大的输入上窒息,并且合理地处理对应于因子和非因子观察输入的表输入?

3
不知道是否有table的反函数,但我猜你可以稍微改进下代码。例如,我会尝试:lev<-expand.grid(dimnames(mytable));lev[rep(1:nrow(lev),as.vector(mytable)),] - nicola
@Nicola:你说得对,谢谢。还有另一个暂时的评论(不久后被撤回了),也建议使用as.data.frame.table()可以帮助我们解决一半的问题... - texb
1
不一定更好,但是一旦使用 as.data.frame,你可以这样做:DF[rep(rownames(DF), DF$Freq), -ncol(DF)],这看起来表面上更简单一些。 - BrodieG
2个回答

2
我认为你的方案非常不错。无论如何,我处理这个问题的方式都很相似:
tableinv <- function(x){
      y <- x[rep(rownames(x),x$Freq),1:(ncol(x)-1)]
      rownames(y) <- c(1:nrow(y))
      return(y)}
survivors <- as.data.frame(Titanic)
surv.invtab <- tableinv(survivors)

产生的结果
> head(surv.invtab)
  Class  Sex   Age Survived
1   3rd Male Child       No
2   3rd Male Child       No
3   3rd Male Child       No
4   3rd Male Child       No
5   3rd Male Child       No
6   3rd Male Child       No

关于使用函数tableinv()的花例,需要首先将数据转换为数据框:

flower.freqs <- with(iris,table(Petal=cut(Petal.Width,2),Species))
flower.freqs <- as.data.frame(flower.freqs)
flower.invtab <- tableinv(flower.freqs)

在这种情况下的结果是:
> head(flower.invtab)
         Petal Species
1 (0.0976,1.3]  setosa
2 (0.0976,1.3]  setosa
3 (0.0976,1.3]  setosa
4 (0.0976,1.3]  setosa
5 (0.0976,1.3]  setosa
6 (0.0976,1.3]  setosa

希望这能帮到你。

0
在处理一维频率数据的特定情况下,有一种简单的方法。让我们举个例子:
mytable = table(mtcars$cyl)
####  4  6  8 
#### 11  7 14 

一个简单的函数来检索扩展数据:
InvTable = function(tb, random = TRUE){
  output = rep(names(tb), tb)
  if (random) { output <- base::sample(output, replace=FALSE) }
  return(output)
}
InvTable(mytable, T)
#### [1] "4" "8" "8" "4" "4" "6" "6" ...

这不完全是用户的需求,但我认为在许多类似情况下它可能非常有用。 只需注意结果是字符格式,这并不总是我们所需要的(如果需要,请添加 as.numeric)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接