I have created two list with my data set, I am my code helps to match the two list if there are elements in one list that are not in the other using attributes that have been assigned to the two list.
library(lubridate)
library(tidyverse)
library(purrr)
date <- rep_len(seq(dmy("01-01-2011"), dmy("01-01-2013"), by = "days"), 300)
ID <- rep(c("A","B", "C"), 300)
df <- data.frame(date = date,
x = runif(length(date), min = 60000, max = 80000),
y = runif(length(date), min = 800000, max = 900000),
ID)
df$month <- month(df$date)
df$year <- year(df$date)
# Create first list
int1 <- df %>%
mutate(new = floor_date(date, '10 day')) %>%
mutate(new = if_else(day(new) == 31, new - days(10), new)) %>%
group_by(ID, new) %>%
filter(month == "1") %>%
group_split()
# Create second list
int2 <- df %>%
mutate(new = floor_date(date, '10 day')) %>%
mutate(new = if_else(day(new) == 31, new - days(10), new)) %>%
group_by(ID, new) %>%
filter(month == "2") %>%
group_split()
int1 <- int1[-c(3,6)]
# Convenience function to grab the attributes for you
check <- function(list, attribute_name) {
return(attr(list, attribute_name))
}
# Add an attribute to hold the attributes of each list element
attr(int1, "match") <- data.frame(id = sapply(int1, function(x) paste(x$ID[1])),
interval_start_date = sapply(int1, function(x) paste(x$new[1]))
)
# Check the attributes
check(int1)
# Add an attribute "tab" to hold the attributes of each list element
attr(int2, "match") <- data.frame(id = sapply(int2, function(x) paste(x$ID[1])),
interval_start_date = sapply(int2, function(x) paste(x$new[1]))
)
# Check the attributes
check(int2)
# Creates an index for the two list based on the attributes,
i1 <- with(check(int2, "match"), paste(id, format(as.Date(interval_start_date),
"%Y-%d"))) %in%
with(check(int1, "match"), paste(id, format(as.Date(interval_start_date),
"%Y-%d")))
out <- int2[i1]
The code works, and it correctly provides the output, but when I put the code into a function, it ends up giving an error and ultimately does not work.
match_intervals <- function(attribute_name, list1, list2, id_col, interval_col){
# Creates an index for the two list based on the attributes,
i1 <- with(check(list2, attribute_name), paste(id_col, format(as.Date(interval_col),
"%Y-%d"))) %in%
with(check(list1, attribute_name), paste(id_col, format(as.Date(interval_col),
"%Y-%d")))
out <- list2[i1]
return(out)
}
int2 <- match_intervals(attribute_name = "match", int1, int2, id,
interval_col = interval_start_date)
I get this error:
Error in as.Date(interval_col) : object 'interval_start_date' not found and/or
Error in as.Date.default(interval_col) : do not know how to convert 'interval_col' to class “Date”
Any thoughts on what might be happening and how I can fix this?
