如果我有一个如下数据框,第一行是列名(这里不包括行名)
A B C D E F G H I
a b c a a b c c c
1 2 3 4 5 6 7 8 9
我如何能够创建一个新的数据框:
a b c
1 2 3
4 6 7
5 NA 8
NA NA 9
注意NA。对于空值。
更新
If d.frame is the dataframe in question:
new.df <- data.frame();
firstrow <- d.frame[,1]
names <- unique(firstrow)
for (n in names) {
#cbind.fill is part of a package plyr
new.df <- cbind.fill(new.df, frame[3,which(firstrow == n)])
}
colnames(new.df) <- names;
我认为这很有效。但它效率不高,依赖第三方方案。有什么建议吗?
答案 0 :(得分:2)
这是另一种解决方案,基于cbind a df with an empty df (cbind.fill?)
中的函数cbind.fill
cbind.fill<-function(...){
nm <- list(...)
nm<-lapply(nm, as.matrix)
n <- max(sapply(nm, nrow))
do.call(cbind, lapply(nm, function (x)
rbind(x, matrix(, n-nrow(x), ncol(x)))))
}
df <- read.table(text = "A B C D E F G H I
a b c a a b c c c
1 2 3 4 5 6 7 8 9", header = T, as.is=T)
df <- as.matrix(df)
do.call(cbind.fill, split(df[2,], df[1,]))
另一个解决方案
df <- as.matrix(df)
lst <- split(df[2,], df[1,])
m <- max(sapply(lst, length))
result <- sapply(lst, function(x) {length(x) <- m; x})
答案 1 :(得分:0)
无法找到一个简单的解决方案,所以这里有一个选项,使用您在评论中请求的基数R.无论您在原始数据中有多少列
,此解决方案都将有效temp <- read.table(text = "A B C D E F G H I
a b c a a b c c c
1 2 3 4 5 6 7 8 9", header = T) # your data
temp <- data.frame(t(temp))
lengths <- table(temp[, 1])
maxval <- max(lengths)
data.frame(do.call(cbind, lapply(levels(temp[, 1]), function(x) c(x, temp[temp[, 1] == x, 2], rep(NA, maxval - lengths[x])))))
## X1 X2 X3
## 1 a b c
## 2 1 2 3
## 3 4 6 7
## 4 5 <NA> 8
## 5 <NA> <NA> 9
答案 2 :(得分:0)
我会t
改变原始的两行data.frame
,创建一个“时间”变量,使用reshape
重新组织数据,t
会调整结果。
像这样:
x <- t(mydf)
y <- data.frame(cbind(x, ave(x[, 1], x[, 1], FUN = seq_along)))
t(reshape(y, direction = "wide", idvar = "X1", timevar = "X3"))
# A B C
# X1 "a" "b" "c"
# X2.1 "1" "2" "3"
# X2.2 "4" "6" "7"
# X2.3 "5" NA "8"
# X2.4 NA NA "9"