How to append group row into dataframe

2019-03-15 00:11发布

I have this df1:

A B C
1 2 3
5 7 9

where A B C are columns names.

I have another df2 with one column:

A
1
2
3
4

I would like to append df2 for each column of df1, creating this final dataframe:

A B C 
1 2 3
5 7 9
1 1 1
2 2 2
3 3 3
4 4 4

is it possible to do it?

9条回答
霸刀☆藐视天下
2楼-- · 2019-03-15 00:44
data.frame(sapply(df1, c, unlist(df2)), row.names = NULL)
#  A B C
#1 1 2 3
#2 5 7 9
#3 1 1 1
#4 2 2 2
#5 3 3 3
#6 4 4 4

DATA

df1 = structure(list(A = c(1L, 5L), B = c(2L, 7L), C = c(3L, 9L)), .Names = c("A", 
"B", "C"), class = "data.frame", row.names = c(NA, -2L))

df2 = structure(list(A = 1:4), .Names = "A", class = "data.frame", row.names = c(NA, 
-4L))
查看更多
时光不老,我们不散
3楼-- · 2019-03-15 00:44

A solution from purrr, which uses map_dfc to loop through all columns in df1 to combine all the elements with df2$A.

library(purrr)

map_dfc(df1, ~c(., df2$A))

# A tibble: 6 x 3
      A     B     C
  <int> <int> <int>
1     1     2     3
2     5     7     9
3     1     1     1
4     2     2     2
5     3     3     3
6     4     4     4

Data

df1 <- structure(list(A = c(1L, 5L), B = c(2L, 7L), C = c(3L, 9L)), .Names = c("A", 
                                                                               "B", "C"), class = "data.frame", row.names = c(NA, -2L))

df2 <- structure(list(A = 1:4), .Names = "A", class = "data.frame",
                 row.names = c(NA, -4L))
查看更多
我想做一个坏孩纸
4楼-- · 2019-03-15 00:45

Here is a base R method with rbind, rep, and setNames:

rbind(dat, setNames(data.frame(rep(dat1, ncol(dat))), names(dat)))
  A B C
1 1 2 3
2 5 7 9
3 1 1 1
4 2 2 2
5 3 3 3
6 4 4 4

Edit: turns outdata.frame isn't necessary:

rbind(dat, setNames(rep(dat1, ncol(dat)), names(dat)))

will work.

data

dat <- 
structure(list(A = c(1L, 5L), B = c(2L, 7L), C = c(3L, 9L)), .Names = c("A", 
"B", "C"), class = "data.frame", row.names = c(NA, -2L))

dat1 <-
structure(list(A = 1:4), .Names = "A", row.names = c(NA, -4L),
class = "data.frame")
查看更多
Lonely孤独者°
5楼-- · 2019-03-15 00:45

For the sake of completeness, here is data.table approach which doesn't require to handle column names:

library(data.table)
setDT(df1)[, lapply(.SD, c, df2$A)]
   A B C
1: 1 2 3
2: 5 7 9
3: 1 1 1
4: 2 2 2
5: 3 3 3
6: 4 4 4

Note that the OP has described df2 to consist only of one column.

There is also a base R version of this approach:

data.frame(lapply(df1, c, df2$A))
  A B C
1 1 2 3
2 5 7 9
3 1 1 1
4 2 2 2
5 3 3 3
6 4 4 4

This is similar to d.b's approach but doesn't required to deal with column names.

查看更多
我想做一个坏孩纸
6楼-- · 2019-03-15 00:46

By analogy with @useR's excellent Base R answer, here's a tidyverse solution:

library(purrr)

map2_df(df1, df2, c)
  A B C
1 1 2 3
2 5 7 9
3 1 1 1
4 2 2 2
5 3 3 3
6 4 4 4

Here are a few other (less desirable) options from when I first answered this question.

library(dplyr)

bind_rows(df1, df2 %>% mutate(B=A, C=A))

Or, if we want to dynamically get the number of columns and their names from df1:

bind_rows(df1,
          df2[,rep(1,ncol(df1))] %>% setNames(names(df1)))

And one more Base R method:

rbind(df1, setNames(df2[,rep(1,ncol(df1))], names(df1)))
查看更多
ゆ 、 Hurt°
7楼-- · 2019-03-15 00:53

We can use base R methods

rbind(df1, setNames(as.data.frame(do.call(cbind, rep(list(df2$A), 3))), names(df1)))
#  A B C
#1 1 2 3
#2 5 7 9
#3 1 1 1
#4 2 2 2
#5 3 3 3
#6 4 4 4

data

df1 <- structure(list(A = c(1L, 5L), B = c(2L, 7L), C = c(3L, 9L)), .Names = c("A", 
"B", "C"), class = "data.frame", row.names = c(NA, -2L))

df2 <- structure(list(A = 1:4), .Names = "A", class = "data.frame",
row.names = c(NA, -4L))
查看更多
登录 后发表回答