Fleaf
Fleaf

Reputation: 71

Adding column to a dataframe in R based on matching conditions in another dataframe

I have 2 data frames and I would like to add a column to one and add values from another data frame based on matching conditions. I would then like to repeat this for many large datasets.

# Example dataframe

DF1 <- data.frame(Batch = c('a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'b'),
           Patch1 = c(1, 1, 2, 2, 3, 3, 1, 1, 2, 2, 3, 3),
           Patch2 = c(2, 3, 1, 3, 1, 2, 2, 3, 1, 3, 1, 2))

DF2 <- data.frame(Batch = c('a', 'a', 'a', 'b', 'b', 'b'),
                             Patch = c(1, 2, 3, 1, 2, 3),
                             Pop_size = sample(1:300, size=6, replace=TRUE)) 

To DF1 I would like to add 2 columns (Patch1_popsize and Patch2_popsize) where the Pop_size is given in DF2 with corresponding Patch numbers for a given Batch

Upvotes: 2

Views: 2309

Answers (3)

akrun
akrun

Reputation: 887831

We can use data.table methods which would be faster and efficient

library(data.table)
setDT(DF1)[DF2, Patch1_Pop_size := Pop_size,
  on = .(Batch, Patch1 = Patch)][DF2, 
   Patch2_Pop_size := Pop_size, on = .(Batch, Patch2 = Patch)]

Upvotes: 0

Marcos P&#233;rez
Marcos P&#233;rez

Reputation: 1250

Try this:

DF3 <- merge(DF1,DF2, by.x = c("Batch","Patch1"), by.y=c("Batch","Patch"), all.x=TRUE) %>%
      rename(Pop_size1=Pop_size)
DF3 <- merge(DF3,DF2, by.x = c("Batch","Patch2"), by.y=c("Batch","Patch"), all.x=TRUE) %>%
      rename(Pop_size2=Pop_size)

Upvotes: 2

Duck
Duck

Reputation: 39613

Try using match() in this style:

#Code
DF1$Patch1_Pop_size <- DF2[match(paste(DF1$Batch,DF1$Patch1),paste(DF2$Batch,DF2$Patch)),"Pop_size"]
DF1$Patch2_Pop_size <- DF2[match(paste(DF1$Batch,DF1$Patch2),paste(DF2$Batch,DF2$Patch)),"Pop_size"]

Output:

DF1
   Batch Patch1 Patch2 Patch1_Pop_size Patch2_Pop_size
1      a      1      2             137             254
2      a      1      3             137             211
3      a      2      1             254             137
4      a      2      3             254             211
5      a      3      1             211             137
6      a      3      2             211             254
7      b      1      2              78              81
8      b      1      3              78              43
9      b      2      1              81              78
10     b      2      3              81              43
11     b      3      1              43              78
12     b      3      2              43              81

Upvotes: 2

Related Questions