如何解决在 R 中使用组重塑多列
我有一个数据集 my.data
,包含多列数字数据(x.1
、x.3
和 x.5
)和两个组 (CC
) .
my.data <- read.table(text = '
AA BB CC x.1 x.3 x.5
aaa 3 1 5 10 15
aaa 3 2 20 25 30
aaa 4 1 50 100 150
aaa 4 2 200 250 300
aaa 5 1 500 1000 1500
aaa 5 2 2000 2500 3000
',header = TRUE,stringsAsFactors = FALSE)
我想通过 x.1
重塑 x.3
、x.5
和 CC
。以下两个数据集中的任何一个都是理想的。我意识到这可能是重复的,但到目前为止我已经查看了大约两打 reshape
问题,但没有找到类似的问题。
desired.result.1 <- read.table(text = '
CC x.1 x.3 x.5
1 5 50 500
1 10 100 1000
1 15 150 1500
2 20 200 2000
2 25 250 2500
2 30 300 3000
',stringsAsFactors = FALSE)
desired.result.2 <- read.table(text = '
CC x.1 x.3 x.5
1 5 50 500
2 20 200 2000
1 10 100 1000
2 25 250 2500
1 15 150 1500
2 30 300 3000
',stringsAsFactors = FALSE)
到目前为止,我实际上已经提出了两种不同的解决方案(如下所示)。但是这两种解决方案似乎都过于复杂。我一直想知道是否可能有一个更好的单线 R
。
这是第一个解决方案。它结合了 sapply
和 reshape
。
new.data <- do.call(cbind,sapply(unique(my.data$BB),function(x) {reshape(my.data[my.data$BB == x,3:6],idvar = "CC",varying = list(2:4),v.names = "x",direction = "long")[3]}))
new.data <- data.frame(CC = rep(c(1,2),(nrow(new.data)/2)),new.data)
colnames(new.data) <- c('CC',paste0('x.',seq(1,5,by=2)))
all.equal(new.data,desired.result.2)
#[1] TRUE
这是第二种解决方案。它不使用 sapply
。但是,它仍然需要大量的后期处理:
new.data2 <- t(reshape(my.data,idvar = c('AA','BB'),timevar='CC',direction = 'wide'))[3:(nrow(new.data)+2),]
new.data2 <- data.frame(CC = rep(c(1,each=(nrow(my.data)/2)),new.data2)
colnames(new.data2) <- c('CC',by=2)))
new.data2 <- apply(new.data2,2,as.numeric)
new.data2 <- data.frame(new.data2)
all.equal(new.data2,desired.result.1)
#[1] TRUE
解决方法
试试下面的 data.table
选项
setDT(my.data)[,setNames(transpose(.SD),names(.SD)),CC,.SDcols = patterns("x\\.\\d+")
]
给出
CC x.1 x.3 x.5
1: 1 5 50 500
2: 1 10 100 1000
3: 1 15 150 1500
4: 2 20 200 2000
5: 2 25 250 2500
6: 2 30 300 3000
,
这是一个 tidyverse
选项,用于在每个组内内部转置数据。
library(dplyr)
library(tidyr)
my.data %>%
pivot_longer(cols = starts_with('X')) %>%
arrange(CC,name) %>%
group_by(CC,name) %>%
mutate(row = row_number()) %>%
group_by(CC) %>%
mutate(value = value[order(row)]) %>%
ungroup %>%
select(-row) %>%
pivot_wider() %>%
select(-AA,-BB)
# CC x.1 x.3 x.5
# <int> <int> <int> <int>
#1 1 5 50 500
#2 1 10 100 1000
#3 1 15 150 1500
#4 2 20 200 2000
#5 2 25 250 2500
#6 2 30 300 3000
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。