I am trying to find potential matches between two data frames, based 3 criteria. I have setup a nested for loop, which for each row of DF1 to checks every row of DF2 using 3 IF statements as the checking criteria. If there is a match, the results (name from DF1 and ID for DF2) are captured in DF3. Due to the criteria it is possible to match some row multiple times. The code develop works and provides the output I am chasing, but it is too slow for the real datasets which are much larger. I have tried to vectorize the approach, but have failed (apply, lapply etc). Any advice on how to speed up this code would be greatly appreciated.
#create an empty dataframe to capture the matches
DF3 <- data.frame(name=integer(0), ID=integer(0))
set.seed(123)
DF1 <- data.frame(
sort = rep(c("car", "tree", "bus", "house"), 3),
Date1 = as.Date(c("01/02/15", "04/02/15", "04/03/15", "05/09/16", "01/04/15", "04/02/15", "04/06/15", "05/09/16",
"04/08/15", "05/10/16", "01/04/15", "04/02/15" ), format = "%d/%m/%y"),
Date2 = as.Date(c("07/02/15", "12/02/15", "14/03/15", "10/10/16", "02/04/15", "06/02/15", "04/06/15", "05/09/16",
"05/08/15", "07/10/16", "02/04/15", "05/02/15"), format = "%d/%m/%y"),
word1 = c(1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0),
word2 = c(1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0),
name = sample.int(10000,12, replace = F)
)
DF2 <- data.frame(
location = rep(c("car1", "tree2", "business", "fox"), 3),
start = as.Date(c("05/02/15", "06/02/15", "10/03/15", "10/01/17", "05/02/15", "05/02/15", "10/03/15", "10/01/17",
"05/02/15", "06/10/15", "10/03/15", "10/01/17"), format = "%d/%m/%y"),
word1 = rep(c(1, 0), 6),
word2 = rep(c(1, 0), 6),
ID = sample.int(10000,12, replace = F)
)
i <- 0
j <- 0
for(j in 1:nrow(DF1)){
for (i in 1:nrow(DF2)){
if(grepl(DF1$sort[j], DF2$location[i])){ #check if the sort word appears with the location string
if(between(DF2$start[i], DF1$Date1[j], DF1$Date2[j])){ #check if the start date is between Date1 and Date 2
if(DF1$word1[j] + DF2$word1[i] == 2 | DF1$word2[j] + DF2$word2[i] == 2){ #check if there is 1 in both the word1 or word2 column
temp <- data.frame(name=DF1$name[j], ID=DF2$ID[i])
DF3 <- rbind(DF3, temp)
}
}
}
}
}
Expected Output
name ID
1 2463 9145
2 2463 2567
3 2463 1614
4 8718 2888
5 8718 9982
6 8718 4469