R 数据转换 - 列到行并聚合
R Data transform - Columns to Rows and aggregate
我正在努力处理 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,]))
)
也许您正在寻找 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<-
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)
您还可以使用 dplyr
和 tidyr
在长格式和宽格式之间切换(尽管在这种特殊情况下,使用 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)
我正在努力处理 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,]))
)
也许您正在寻找 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<-
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)
您还可以使用 dplyr
和 tidyr
在长格式和宽格式之间切换(尽管在这种特殊情况下,使用 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)