在R中对具有相同名称的列进行分组

时间:2014-07-15 19:52:51

标签: r

如果我有一个如下数据框,第一行是列名(这里不包括行名)

   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;

我认为这很有效。但它效率不高,依赖第三方方案。有什么建议吗?

3 个答案:

答案 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"