1
votes

I need to add values of same column names across four different data frames in R. The problem is that there are different number of columns in these 4 data frames with only one data frame out of them containing all the columns. Rest of the data frames have a subset of column names of the 1st data frame. Number of rows are equal across 4 data frames.

Minimum replicable example is:

Say there are 4 data frames with the structure as follows:

df1 <- setNames(data.frame(matrix(ncol = 10, nrow = 900)), c("Red", "Blue", "Yellow", "Green", "Orange", "Pink", "Brown", "Black", "Grey", "Purple"))
df2 <- setNames(data.frame(matrix(ncol = 9, nrow = 900)), c("Red", "Blue", "Yellow", "Orange", "Pink", "Brown", "Black", "Grey", "Purple"))
df3 <- setNames(data.frame(matrix(ncol = 8, nrow = 900)), c("Red", "Blue", "Yellow", "Orange", "Pink", "Brown", "Black", "Purple"))
df4 <- setNames(data.frame(matrix(ncol = 6, nrow = 900)), c("Red", "Yellow", "Green", "Orange", "Brown", "Purple")

Assume that each of these columns in the four data frames have integer values across 900 rows. How do I return a data frame which is basically the addition of values of same columns across four data frames? In other words, df.sum[1:10] <- df1[1:10] + df2[1:9] + df3[1:8] + df4[1:6], but while adding identify the same columns to be added

1
You are doing the sum of NA elements? - akrun
No, I have the integer values in all the 900 rows - victor8910

1 Answers

1
votes

If there are no NA elements, we can do the + after making the dimensions same

lst <- mget(paste0("df", 1:4)) # get the datasets in a list
nm1 <- Reduce(union, lapply(lst, names)) # find all the column names
# assign missing columns in each of the dataset with value 0
# get the `+` of all list elements with Reduce
dfout <- Reduce(`+`, lapply(lst, function(x) {
        x[setdiff(nm1, names(x))] <- 0
        x[nm1]}))
dim(dfout)
#[1] 900  10

data

set.seed(24)
df1 <- setNames(data.frame(matrix(rnorm(900 * 10), ncol = 10, nrow = 900)), 
    c("Red", "Blue", "Yellow", "Green", "Orange", "Pink", 
  "Brown", "Black", "Grey", "Purple"))
df2 <- setNames(data.frame(matrix(rnorm(900 * 9), ncol = 9, nrow = 900)), 
   c("Red", "Blue", "Yellow", "Orange", "Pink", "Brown",
        "Black", "Grey", "Purple"))
df3 <- setNames(data.frame(matrix(rnorm(900 * 8), ncol = 8, nrow = 900)), 
      c("Red", "Blue", "Yellow", "Orange", "Pink", "Brown", "Black", "Purple"))
df4 <- setNames(data.frame(matrix(rnorm(900 * 6), ncol = 6, nrow = 900)),
     c("Red", "Yellow", "Green", "Orange", "Brown", "Purple"))