I have two dataframes with some columns that are shared and others that are different. I want to take the one-row dataframe and add all of its column values to every value in the matching columns for the other data frame.
My data looks like this:
DF1
Location | X123 | X124 | X125 |
---|---|---|---|
USA | 6 | 8 | 9 |
DF2
Location | Fips | Code | X123 | X124 | X125 |
---|---|---|---|---|---|
Kansas | 183844 | bb | 0 | 3 | 4 |
Virginia | 198334 | cc | 1 | 5 | 0 |
So, I want to add the DF1 USA column values to the matching column values in DF2.
My output would look like:
Location | Fips | Code | X123 | X124 | X125 |
---|---|---|---|---|---|
Kansas | 183844 | bb | 6 | 11 | 13 |
Virginia | 198334 | cc | 7 | 13 | 9 |
You can recreate my example data with this code:
values<-c("USA", 6,8,9)
columns<-c("Location","X123", "X124", "X125")
df1<-rbind(columns,values)
df1<-as.data.frame(df1)
colnames(df1)<-columns
df1<-df1[-1,]
valuesR1<-c("Kansas", 183844, "bb", 0, 3,4)
valuesR2<-c("Virgnia", 198334, "cc", 1, 5,0)
df2<-rbind(valuesR1, valuesR2)
columns<-c("Location", "Fips", "Code", "X123", "X124", "X125")
colnames(df2)<-columns
df2<-as.data.frame(df2)
I've been looking at different types of rbinds, but so far haven't been able to find something that will add the columns correctly.
Any assistance would be greatly appreciated.
CodePudding user response:
Here is a way.
Get the numeric columns of both data.frames, then intersect those column names. Finally, for each common column name, add the respective columns of df1
to df2
.
Also, the way you create the data example, by rows, is not the best. Each row vector becomes a character vector. R's data.frames are lists of vectors with some attributes set, like the dim
attribute, and the vectors are column vectors making it possible for df's to have columns of different data classes. The first two code lines below are meant to coerce the vectors that should be numeric to actual numeric.
df1[-1] <- lapply(df1[-1], as.numeric)
df2[-c(1,3)] <- lapply(df2[-c(1,3)], as.numeric)
i_num1 <- sapply(df1, is.numeric)
i_num2 <- sapply(df2, is.numeric)
common <- intersect(names(df1)[i_num1], names(df2)[i_num2])
df2[common] <- lapply(common, \(x) df1[[x]] df2[[x]])
df2
#> Location Fips Code X123 X124 X125
#> valuesR1 Kansas 183844 bb 6 11 13
#> valuesR2 Virgnia 198334 cc 7 13 9
Created on 2022-11-14 with reprex v2.0.2