Using a function and lapply for a date sequence in R

I am trying to not use a for loop and use a function and lapply to generate a sequence of dates separated by days and append it to data.
First, I tried

    x = data.frame(
        date = seq.Date(from = as.Date((q)[['d1']]),to = as.Date(q[['d2']]),by = "days"),
        m = (q)[['m']],
        stringsAsFactors = F
    )
    return(x)
}
y = list(
    d1 = as.Date(c("2012/01/31","2012/01/14")),
    d2 = as.Date(c("2012/01/31","2012/01/21")),
    m = c(100,75))
z <- do.call(rbind,lapply(y,fn))

but I get Error in [[.default(q, "d1") : subscript out of bounds and I tried to fix that using get()

Then I tried

    x = data.frame(
        date = seq.Date(from = as.Date(get(q)[['d1']]),to = as.Date(get(q[['d2']]),by = "days"),
        m = get(q)[['m']],
        stringsAsFactors = F
    )
    return(x)
}
y = list(
    d1 = as.Date(c("2012/01/31","2012/01/14")),
    d2 = as.Date(c("2012/01/31","2012/01/21")),
    m = c(100,75))
z <- do.call(rbind,lapply(y,fn))

I tried this but I get Error in get(q) : invalid first argument

>Solution :

When you do lapply on a list, it applies the function to each column individually. Your lapply(y, fn) is equivalent to list(fn(y[["d1"]]), fn(y[["d2"]]), fn(y[["q"]])), because those are the list items. Of course this doesn’t work because your function is expecting a list with a single value for each of d1, d2, and q as input.

Making minimal changes, we can convert your list to a data frame and applying the function to rows:

dy = as.data.frame(y)
result = do.call(rbind, lapply(1:nrow(dy), \(i) fn(dy[i, ])))
result
#         date   m
# 1 2012-01-31 100
# 2 2012-01-14  75
# 3 2012-01-15  75
# 4 2012-01-16  75
# 5 2012-01-17  75
# 6 2012-01-18  75
# 7 2012-01-19  75
# 8 2012-01-20  75
# 9 2012-01-21  75

Leave a Reply