【问题标题】:Transposing Dataframe post aggregation转置 Dataframe 后聚合
【发布时间】:2018-06-14 14:04:47
【问题描述】:

我在正确转置我的数据时遇到了一些困难。我正在尝试获取列的平均值和 sd 的列表,其中列名现在是行。我能够使用以下代码创建方法和 sd:

data(iris)

mydata <- do.call(data.frame, aggregate(. ~ Species, iris, function(x) c(mean = mean(x), sd = sd(x))))

创建表:

&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Species&lt;/th&gt;&lt;th&gt;Sepal.Length.mean&lt;/th&gt;&lt;th&gt;Sepal.Length.sd&lt;/th&gt;&lt;th&gt;Sepal.Width.mean&lt;/th&gt;&lt;th&gt;Sepal.Width.sd&lt;/th&gt;&lt;th&gt;Petal.Length.mean&lt;/th&gt;&lt;th&gt;Petal.Length.sd&lt;/th&gt;&lt;th&gt;Petal.Width.mean&lt;/th&gt;&lt;th&gt;Petal.Width.sd&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;setosa&lt;/td&gt;&lt;td&gt;5.006&lt;/td&gt;&lt;td&gt;0.3524897&lt;/td&gt;&lt;td&gt;3.428&lt;/td&gt;&lt;td&gt;0.3790644&lt;/td&gt;&lt;td&gt;1.462&lt;/td&gt;&lt;td&gt;0.173664&lt;/td&gt;&lt;td&gt;0.246&lt;/td&gt;&lt;td&gt;0.1053856&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;versicolor&lt;/td&gt;&lt;td&gt;5.936&lt;/td&gt;&lt;td&gt;0.5161711&lt;/td&gt;&lt;td&gt;2.77&lt;/td&gt;&lt;td&gt;0.3137983&lt;/td&gt;&lt;td&gt;4.26&lt;/td&gt;&lt;td&gt;0.469911&lt;/td&gt;&lt;td&gt;1.326&lt;/td&gt;&lt;td&gt;0.1977527&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;virginica&lt;/td&gt;&lt;td&gt;6.588&lt;/td&gt;&lt;td&gt;0.6358796&lt;/td&gt;&lt;td&gt;2.974&lt;/td&gt;&lt;td&gt;0.3224966&lt;/td&gt;&lt;td&gt;5.552&lt;/td&gt;&lt;td&gt;0.5518947&lt;/td&gt;&lt;td&gt;2.026&lt;/td&gt;&lt;td&gt;0.27&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

我希望表格如下所示:

&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt; &lt;/th&gt;&lt;th&gt;Setosa&lt;/th&gt;&lt;th&gt; &lt;/th&gt;&lt;th&gt;Versicolor&lt;/th&gt;&lt;th&gt; &lt;/th&gt;&lt;th&gt;Virginica&lt;/th&gt;&lt;th&gt; &lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt;Mean&lt;/td&gt;&lt;td&gt;SD&lt;/td&gt;&lt;td&gt;Mean&lt;/td&gt;&lt;td&gt;SD&lt;/td&gt;&lt;td&gt;Mean&lt;/td&gt;&lt;td&gt;SD&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sepal.Length&lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sepal.Width&lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Petal.Length&lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Petal.Width&lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;td&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

我意识到获取第二个标头很可能需要 kable 中的 add_header_above 函数,但在我到达那里之前,我很难将数据帧构造成我想要的。我一直在摆弄 cast 和 melt 功能,但运气不佳。

任何建议将不胜感激!

~杰克

【问题讨论】:

  • 首先,你为什么要用do.callaggregate??不需要do.call`,因为aggregate 的结果已经是一个数据帧
  • 建议使用 do.call link,因为第二个会导致聚合生成矩阵。如果没有 do.call,则 sd 列不会显示在 data.frame 中
  • 好吧,它确实出现了

标签: r dplyr transpose kable


【解决方案1】:

我猜你在找这个?

  `colnames<-`(do.call(rbind,by(t(mydata[-1]),rep(names(iris[-5]),each=2),unlist)),rep(c("Mean","Sd"),3))
              Mean        Sd  Mean        Sd  Mean        Sd
Petal.Length 1.462 0.1736640 4.260 0.4699110 5.552 0.5518947
Petal.Width  0.246 0.1053856 1.326 0.1977527 2.026 0.2746501
Sepal.Length 5.006 0.3524897 5.936 0.5161711 6.588 0.6358796
Sepal.Width  3.428 0.3790644 2.770 0.3137983 2.974 0.3224966

首先,因为我只处理数字列,所以我通过iris[-5] 摆脱了Species column。另外,由于我不需要mydata 的第一列,所以我摆脱了它。为什么我重复了两次?有两个功能。为什么我重复了3次,有3种……

【讨论】:

    【解决方案2】:

    这是一个使用 tidyverse 和 tables 包的解决方案。首先,我们使用gather() 来制作一个窄格式的整洁数据集。窄格式允许我们同时使用SpeciesflowerAttribute 作为表中的因子变量,并且无需转置数据。

    其次,我们使用tables::tabular() 函数生成一个表,该表在列维度上具有物种均值和标准差,在行维度上具有花属性。

    data(iris)
    library(tables)
    library(tidyverse)
    tidyIris <- gather(iris,key=flowerAttribute,value=value,
                     Sepal.Length,Sepal.Width,Petal.Length,Petal.Width)
    # factors required for tabular()
    tidyIris$flowerAttribute <- as.factor(tidyIris$flowerAttribute)
    tabular((flowerAttribute) ~ Format(digits=2)*(Species)*(value)*(mean + sd), 
           data=tidyIris )
    

    ...和输出:

    > tabular((flowerAttribute) ~ Format(digits=2)*(Species)*(value)*(mean + sd), 
    +         data=tidyIris )
    
                     Species                                    
                     setosa       versicolor      virginica     
                     value        value           value         
     flowerAttribute mean    sd   mean       sd   mean      sd  
     Petal.Length    1.46    0.17 4.26       0.47 5.55      0.55
     Petal.Width     0.25    0.11 1.33       0.20 2.03      0.27
     Sepal.Length    5.01    0.35 5.94       0.52 6.59      0.64
     Sepal.Width     3.43    0.38 2.77       0.31 2.97      0.32
    

    对于以前使用过 SAS 的用户,tables 包实现类似于 SAS PROC TABULATE 的功能。

    增强输出

    通过对代码进行一些调整,我们可以准确地复制 OP 中请求的输出格式。

    # key syntax elements
    # 1. - renamed flowerAttribute to Attribute using = operator
    # 2. - used Heading() to eliminate the printing of "value" and "Species" on columns
    tabular((Attribute=flowerAttribute) ~ Format(digits=2)*(Heading()*Species)*Heading()*(value)*(mean + sd), 
            data=tidyIris )
    

    ...和输出:

                  setosa       versicolor      virginica     
     Attribute    mean    sd   mean       sd   mean      sd  
     Petal.Length 1.46    0.17 4.26       0.47 5.55      0.55
     Petal.Width  0.25    0.11 1.33       0.20 2.03      0.27
     Sepal.Length 5.01    0.35 5.94       0.52 6.59      0.64
     Sepal.Width  3.43    0.38 2.77       0.31 2.97      0.32
     > 
    

    生成 LaTeX

    最后,要获得排版质量输出,可以使用tabular() 编写可以使用Sweave 编译成PDF 文档的LaTeX 代码。

    latex(tabular((Attribute=flowerAttribute) ~ Format(digits=2)*(Heading()*Species)*Heading()*(value)*(mean + sd), 
            data=tidyIris ))
    

    ...生成 LaTeX 编译成:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-22
      相关资源
      最近更新 更多