【问题标题】:Is there a general inverse of the table() function?是否存在 table() 函数的一般逆函数?
【发布时间】:2019-06-04 17:30:14
【问题描述】:

我知道a little programming 允许转换固定维度的频率表,例如返回由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

我显然很自豪这个 bricolage 从更高维的频率表(例如 Titanic)重构了多属性 data.frame()s - 但是有一个已建立的(内置的,经过实战测试的)通用逆向表() ,理想情况下,它不依赖于特定库,知道如何处理未标记的维度,经过优化,不会因庞大的输入而窒息,并且可以合理地处理与因子和非因子相对应的表输入因素观察输入?

【问题讨论】:

  • 不知道是否有 table 的逆,但我想你可以稍微改进一下你的代码。例如,我会尝试:lev&lt;-expand.grid(dimnames(mytable));lev[rep(1:nrow(lev),as.vector(mytable)),]
  • @Nicola:你是对的,谢谢。另一个临时评论(有人很快又撤回了)也暗示as.data.frame.table() 将把我们带到一半......
  • 不一定更好,但是一旦你使用as.data.frame,你就可以:DF[rep(rownames(DF), DF$Freq), -ncol(DF)],表面上看起来更简单一些。

标签: r


【解决方案1】:

我相信您的解决方案非常好。无论如何,我解决这个问题的方式非常相似:

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

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    在我们处理一维频率数据的特定情况下,有一种简单的方法。举个例子:

    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)。

    【讨论】:

      猜你喜欢
      • 2017-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-23
      • 2018-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多