将两个数据帧一个接一个地组合在一起

时间:2014-09-02 20:04:32

标签: r dataframe

我有两个数据帧,我希望将一个数据帧放在另一个上面,并将第二列的列名称作为新数据帧的一行。列名不同,一个数据框有更多列。

例如:

mydf1 <- data.frame(V1=c(1:5), V2=c(21:25))

mydf1
  V1 V2
1  1 21
2  2 22
3  3 23
4  4 24
5  5 25

mydf2 <- data.frame(C1=c(1:10), C2=c(21:30),C3=c(41:50))

mydf2
C1 C2 C3
1   1 21 41
2   2 22 42
3   3 23 43
4   4 24 44
5   5 25 45
6   6 26 46
7   7 27 47
8   8 28 48
9   9 29 49
10 10 30 50

结果:

    mydf
   V1 V2
 1  1 21 NA
 2  2 22 NA
 3  3 23 NA
 4  4 24 NA
 5  5 25 NA
 6  C1 C2 C3
 7  1 21 41
 8  2 22 42
 9  3 23 43
10  4 24 44
11  5 25 45
12  6 26 46
13  7 27 47
14  8 28 48
15  9 29 49
16 10 30 50

我不在乎是否所有数值都被视为字符。 非常感谢

4 个答案:

答案 0 :(得分:2)

无需任何包装即可轻松完成此操作:

mydf1 <- data.frame(V1=c(1:5), V2=c(21:25))
mydf1[,3] <- NA
names(mydf1) <- c("one", "two", "three")
mydf2 <- data.frame(C1=c(1:10), C2=c(21:30),C3=c(41:50))
names <- t(as.data.frame(names(mydf2)))
names <- as.data.frame(names)
names(mydf2) <- c("one", "two", "three")
names(names) <- c("one", "two", "three")
mydf3 <- rbind(mydf1, names)
mydf4 <- rbind(mydf3, mydf2)

> mydf4
one two three
1    1  21  <NA>
2    2  22  <NA>
3    3  23  <NA>
4    4  24  <NA>
5    5  25  <NA>
6   C1  C2    C3
7    1  21    41
8    2  22    42
9    3  23    43
10   4  24    44
11   5  25    45
12   6  26    46
13   7  27    47
14   8  28    48
15   9  29    49
16  10  30    50
>     

当然,您可以编辑<- c("one", "two", "three")以根据需要制作最终的列名。例如:

> mydf1 <- data.frame(V1=c(1:5), V2=c(21:25))
> mydf1[,3] <- NA
> names(mydf1) <- c("V1", "V2", "NA")
> mydf2 <- data.frame(C1=c(1:10), C2=c(21:30),C3=c(41:50))
> names <- t(as.data.frame(names(mydf2)))
> names <- as.data.frame(names)
> names(mydf2) <- c("V1", "V2", "NA")
> names(names) <- c("V1", "V2", "NA")
> mydf3 <- rbind(mydf1, names)
> mydf4 <- rbind(mydf3, mydf2)
> row.names(mydf4) <- NULL
> mydf4
V1 V2   NA
1   1 21 <NA>
2   2 22 <NA>
3   3 23 <NA>
4   4 24 <NA>
5   5 25 <NA>
6  C1 C2   C3
7   1 21   41
8   2 22   42
9   3 23   43
10  4 24   44
11  5 25   45
12  6 26   46
13  7 27   47
14  8 28   48
15  9 29   49
16 10 30   50

如果您需要在将其扩展到实际用例时出于任何原因使用包,请尝试meltreshape2包中的plyr。但是,不一定要使用包装。

答案 1 :(得分:1)

这是使用rbind.fill函数的一种方法(plyr包的一部分)。

library(plyr)
setNames(rbind.fill(setNames(mydf1, names(mydf2[seq(mydf1)])), 
                    rbind(names(mydf2), mydf2)), names(mydf1))

   V1 V2   NA
1   1 21 <NA>
2   2 22 <NA>
3   3 23 <NA>
4   4 24 <NA>
5   5 25 <NA>
6  C1 C2   C3
7   1 21   41
8   2 22   42
9   3 23   43
10  4 24   44
11  5 25   45
12  6 26   46
13  7 27   47
14  8 28   48
15  9 29   49
16 10 30   50

答案 2 :(得分:1)

试一试。

将第二个数据集中的列名称指定给向量,然后将第二个集合的名称替换为第一个集合中的名称。然后创建一个列表,其中中间元素是您指定的向量。现在当你打电话给rbind时,它应该没问题,因为一切都是正确的顺序。

d1$V3 <- NA
nm <- names(d2)
names(d2) <- names(d1)
dc <- do.call(rbind, list(d1,nm,d2))
rownames(dc) <- NULL
dc

答案 3 :(得分:1)

我不知道你用write.table尝试了什么,但在我看来,这似乎是要走的路。

我会创建一个类似这样的函数:

myFun <- function(...) {
  L <- list(...)
  temp <- tempfile()
  maxCol <- max(vapply(L, ncol, 1L))
  lapply(L, function(x) 
    suppressWarnings(
      write.table(x, file = temp, row.names = FALSE,
                sep = ",", append = TRUE)))
  read.csv(temp, header = FALSE, fill = TRUE,
           col.names = paste0("New_", sequence(maxCol)),
           stringsAsFactors = FALSE)
}

然后用法就是:

myFun(mydf1, mydf2)
#    New_1 New_2 New_3
# 1     V1    V2      
# 2      1    21      
# 3      2    22      
# 4      3    23      
# 5      4    24      
# 6      5    25      
# 7     C1    C2    C3
# 8      1    21    41
# 9      2    22    42
# 10     3    23    43
# 11     4    24    44
# 12     5    25    45
# 13     6    26    46
# 14     7    27    47
# 15     8    28    48
# 16     9    29    49
# 17    10    30    50

编写函数时,您可以指定两个以上的data.frame作为输入:

mydf3 <- data.frame(matrix(1:8, ncol = 4))
myFun(mydf1, mydf2, mydf3)
#    New_1 New_2 New_3 New_4
# 1     V1    V2            
# 2      1    21            
# 3      2    22            
# 4      3    23            
# 5      4    24            
# 6      5    25            
# 7     C1    C2    C3      
# 8      1    21    41      
# 9      2    22    42      
# 10     3    23    43      
# 11     4    24    44      
# 12     5    25    45      
# 13     6    26    46      
# 14     7    27    47      
# 15     8    28    48      
# 16     9    29    49      
# 17    10    30    50      
# 18    X1    X2    X3    X4
# 19     1     3     5     7
# 20     2     4     6     8