我是R(和编码新手),我正在寻找一种方法将下面的表A显示重新配置到表B中。
表A:
type x1 x2 x3
A 4 6 9
A 7 4 1
A 9 6 2
B 1 3 8
B 2 7 9
我正在寻找可转换为以下内容的代码
表B:
type x1 x2 x3 x1' x2' x3' x1'' x2'' x3''
A 4 6 9 7 4 1 9 6 2
B 1 3 8 2 7 9
真正的表A超过150000行和36列。拥有2100种独特的“类型”值。
感谢您的帮助。
-Shawn
答案 0 :(得分:3)
对我来说,这个解决方案似乎很简单
# split the data frame by type and use unlist, which will provide names
ld <- lapply(split(d[-1], d[["type"]]), unlist)
# gather all the unique names in the list
ldNames <- Reduce(unique, lapply(ld, names))
# use the names to index each list element, which makes them
# all of equal length and suitable for row binding.
do.call(rbind, lapply(ld, function(x) x[ldNames]))
# x11 x12 x13 x21 x22 x23 x31 x32 x33
# A 4 7 9 6 4 6 9 1 2
# B 1 2 NA 3 7 NA 8 9 NA
如果上述输出的顺序不满意,您可以重新排列:
# save the output from above
d2 <- do.call(rbind, lapply(ld, function(x) x[ldNames]))
# reorder the names
ldNames_sorted <- c(matrix(ldNames, ncol = (ncol(d) - 1), byrow = TRUE))
# apply the new order.
d2 <- d2[, ldNames_sorted]
# x11 x21 x31 x12 x22 x32 x13 x23 x33
#A 4 6 9 7 4 1 9 6 2
#B 1 3 8 2 7 9 NA NA NA
要为类型添加列而不是使用行名,一种方法是:
data.frame(type = row.names(d2), d2)
答案 1 :(得分:2)
派对有点晚了,但使用dcast
包的data.table
功能也可以轻松完成,因为您可以使用多个value.var
:< / p>
library(data.table)
dcast(setDT(d), type ~ rowid(type), value.var = c('x1','x2','x3'), sep = '')
给出:
type x11 x12 x13 x21 x22 x23 x31 x32 x33 1: A 4 7 9 6 4 6 9 1 2 2: B 1 2 NA 3 7 NA 8 9 NA
您也可以在基地R中执行以下操作:
d$num <- ave(d$x1, d$type, FUN = seq_along)
reshape(d, idvar = 'type', direction = 'wide', timevar = 'num', sep = '')
答案 2 :(得分:1)
试一试,解决方案不是那么简洁,只是给你一个提示。我认为很多事情都可以改进。
但最后我们必须在这里介绍NAs :(
zz <- "type x1 x2 x3
A 4 6 9
A 7 4 1
A 9 6 2
B 1 3 8
B 2 7 9"
dA <- read.table(text=zz, header=T)
tmp<-(sapply(unique(dA$type), FUN=function(x) as.vector(t(dA[dA$type == x, -1]))))
t(sapply(tmp, '[', seq(max(sapply(tmp, length)))))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 4 6 9 7 4 1 9 6 2
[2,] 1 3 8 2 7 9 NA NA NA
答案 3 :(得分:1)
a <- data.frame(type=c("A", "A","A", "B", "B"), x1 = c(4,7,9,1,2),x2=c(6,4,6,3,7),
x3 = c(9,1,2,8,9))
library(dplyr)
tmp <-
a %>%
group_by(type) %>%
summarise(no_rows = length(type))
for(i in unique(a$type)){
n <- max(tmp$no_rows) - nrow(a[a$type == i,])
nn <- nrow(a)
if(n > 0){
for(ii in 1:n){
a[nn+ii,] <- c(i,NA,NA,NA)
}
}
}
a <- a[order(a$type),]
a$timevar <- seq(1:max(tmp$no_rows) )
b<-reshape(a,timevar="timevar",idvar="type",direction="wide",drop = F)
b
type x1.1 x2.1 x3.1 x1.2 x2.2 x3.2 x1.3 x2.3 x3.3
1 A 4 6 9 7 4 1 9 6 2
4 B 1 3 8 2 7 9 <NA> <NA> <NA>
答案 4 :(得分:1)
@ Hack-R答案的变化:
A$num <- with(A, ave(as.character(type), type, FUN=seq_along) )
tmp <- cbind(A[c(1,5)], stack(A[2:4]))
tmp$time <- paste(tmp$ind, tmp$num, sep=".")
reshape(tmp[c("type","time","values")], idvar="type", timevar="time", direction="wide")
# type values.x1.1 values.x1.2 values.x1.3 values.x2.1 values.x2.2 values.x2.3 values.x3.1 values.x3.2 values.x3.3
#1 A 4 7 9 6 4 6 9 1 2
#4 B 1 2 NA 3 7 NA 8 9 NA
有趣的dplyr版本:
library(dplyr)
library(tidyr)
A %>%
gather(var, value, -type) %>%
group_by(type,var) %>%
mutate(time=seq_along(var)) %>%
ungroup() %>%
unite(grpvar, c(time,var) ) %>%
spread(grpvar, value )
#Source: local data frame [2 x 10]
#
# type 1_x1 1_x2 1_x3 2_x1 2_x2 2_x3 3_x1 3_x2 3_x3
# (chr) (int) (int) (int) (int) (int) (int) (int) (int) (int)
#1 A 4 6 9 7 4 1 9 6 2
#2 B 1 3 8 2 7 9 NA NA NA