【问题标题】:R Data transform - Columns to Rows and aggregateR 数据转换 - 列到行和聚合
【发布时间】:2017-03-13 11:42:11
【问题描述】:

我正在为 R 中的数据转换而苦苦挣扎。我收到的数据属于这种类型:

input <- data.frame(AF = sample(0:1, 100, replace=TRUE),
                CAD = sample(0:1, 100, replace=TRUE),
                CHF = sample(0:1, 100, replace=TRUE),
                DEM = sample(0:1, 100, replace=TRUE),
                DIAB = sample(0:1, 100, replace=TRUE))
input$Counts <- rowSums(input)

我想要实现的输出是:

output <- data.frame(Condition = c('AF', 'CAD', 'CHF', 'DEM', 'DIAB'),
                 '1' = sample(11:20, 5, replace=TRUE),
                 '2' = sample(11:20, 5, replace=TRUE),
                 '3' = sample(11:20, 5, replace=TRUE),
                 '4' = sample(11:20, 5, replace=TRUE),
                 '5' = sample(11:20, 5, replace=TRUE))

其中的交点是与条件匹配的观察计数(现在位于第一列)和行总和(现在是单独的列)。

我的解决方案如下,但我想知道是否有更优雅的解决方案?

data.frame(Condition = colnames(input[ ,1:5]),
       "One" = c(nrow(input[input$AF==1 & input$Counts==1,]),
                 nrow(input[input$CAD==1 & input$Counts==1,]),
                 nrow(input[input$CHF==1 & input$Counts==1,]),
                 nrow(input[input$DEM==1 & input$Counts==1,]),
                 nrow(input[input$DIAB==1 & input$Counts==1,])),
       "Two" = c(nrow(input[input$AF==1 & input$Counts==2,]),
                 nrow(input[input$CAD==1 & input$Counts==2,]),
                 nrow(input[input$CHF==1 & input$Counts==2,]),
                 nrow(input[input$DEM==1 & input$Counts==2,]),
                 nrow(input[input$DIAB==1 & input$Counts==2,])),
       "Three" = c(nrow(input[input$AF==1 & input$Counts==3,]),
                 nrow(input[input$CAD==1 & input$Counts==3,]),
                 nrow(input[input$CHF==1 & input$Counts==3,]),
                 nrow(input[input$DEM==1 & input$Counts==3,]),
                 nrow(input[input$DIAB==1 & input$Counts==3,])),
       "Four" = c(nrow(input[input$AF==1 & input$Counts==4,]),
                 nrow(input[input$CAD==1 & input$Counts==4,]),
                 nrow(input[input$CHF==1 & input$Counts==4,]),
                 nrow(input[input$DEM==1 & input$Counts==4,]),
                 nrow(input[input$DIAB==1 & input$Counts==4,])),
       "Five" = c(nrow(input[input$AF==1 & input$Counts==5,]),
                 nrow(input[input$CAD==1 & input$Counts==5,]),
                 nrow(input[input$CHF==1 & input$Counts==5,]),
                 nrow(input[input$DEM==1 & input$Counts==5,]),
                 nrow(input[input$DIAB==1 & input$Counts==5,])),
       "Six" = c(nrow(input[input$AF==1 & input$Counts==6,]),
                 nrow(input[input$CAD==1 & input$Counts==6,]),
                 nrow(input[input$CHF==1 & input$Counts==6,]),
                 nrow(input[input$DEM==1 & input$Counts==6,]),
                 nrow(input[input$DIAB==1 & input$Counts==6,]))
)

【问题讨论】:

  • 这有助于表达这一点:“按计数拆分,然后按总和聚合每一列”
  • 取行求和,然后计数nrow(input[input$Var==1 &amp; input$Counts==whatever,])只是一种间接的按列求和,拆分然后按计数组合的方式。

标签: r aggregate multiple-columns rows split-apply-combine


【解决方案1】:

也许你正在寻找aggregate

这是一种解决方案。

myMat <- t(aggregate(.~Counts, data=input, FUN=sum)[-1,-1])
myMat
     2  3  4  5 6
AF   3 10 15 15 2
CAD  2 14 16 18 2
CHF  2 14 18 16 2
DEM  4  8 16 18 2
DIAB 5 14 22 17 2

aggregate. ~ Counts 的第一个参数是一个公式,表示按计数对每一列执行一些操作。第二个参数指定数据集,第三个参数说明所需的操作是sum。使用[-1, -1] 从输出中删除第一列和第一行,因为它们与所需结果无关。然后用t 转置此输出。要更改列名,可以使用colnames&lt;-like

colnames(myMat) <- c("One", "Two", "Three", "Four", "Five")

可重复的数据

set.seed(1234)
input <- data.frame(AF = sample(0:1, 100, replace=TRUE),
                    CAD = sample(0:1, 100, replace=TRUE),
                    CHF = sample(0:1, 100, replace=TRUE),
                    DEM = sample(0:1, 100, replace=TRUE),
                    DIAB = sample(0:1, 100, replace=TRUE))
input$Counts <- rowSums(input)

【讨论】:

  • 这有助于表达这一点:“按计数拆分,然后按列总和聚合每一列”
  • 那当然可以节省打字!谢谢你,正是我所追求的。
【解决方案2】:

您还可以使用dplyrtidyr 来切换长宽格式(尽管在这种特殊情况下,使用aggregate 更容易):

library(dplyr)
library(tidyr)

# take the input dataset
input %>%
        # transform to long format
        gather(condition, measurement,AF:DIAB) %>%
        # summarise by Counts and condition
        group_by(Counts, condition) %>%
        summarise(measure = sum(measurement)) %>%
        # transform back to the desired wide format
        spread(Counts, measure)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-22
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 2022-01-03
    • 2019-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多