1) We will assume that what is wanted is an additional column which gives a comma separated string of dates. To do that we form a recursive common table expression (CTE) in SQL.
library(sqldf)
sqldf("with recursive R(id1, id2, date) as (
select * from DF a where a.id1 = id1
union all
select a.id1, a.id2, R.date from DF a join R on a.id1 = R.id2
)
select a.*, group_concat(r.date) dates
from DF a
left join R on a.id1 = R.id1
group by a.rowid")
giving:
id1 id2 date dates
1 101 NA 01.1.2021 01.1.2021,12.1.2021,17.1.2021,18.1.2021
2 102 101 12.1.2021 12.1.2021,17.1.2021,18.1.2021
3 103 102 17.1.2021 17.1.2021,18.1.2021
4 104 103 18.1.2021 18.1.2021
5 105 NA 25.1.2021 25.1.2021
6 106 NA 03.1.2021 03.1.2021
7 107 NA 10.1.2021 10.1.2021,11.1.2021
8 108 107 11.1.2021 11.1.2021
9 109 NA 09.1.2021 09.1.2021
2) If instead what is wanted is a function that takes the data frame and id and produces the date string then use the following. (Note that if id were character rather than numeric then $id at the end of the first select line should be replaced with '$id' .)
library(sqldf)
get_dates <- function(data, id) {
fn$sqldf("with recursive R(id1, id2, date) as (
select * from DF where id1 = $id
union all
select a.id1, a.id2, a.date from DF a join R on a.id2 = R.id1
)
select group_concat(date) dates from R")$dates
}
get_dates(DF, 101)
## [1] "01.1.2021,12.1.2021,17.1.2021,18.1.2021"
get_dates(DF, 107)
## [1] "10.1.2021,11.1.2021"
We could use this function to generate the output in (1):
transform(DF, dates = sapply(id1, get_dates, data = DF))
Note
DF <- structure(list(id1 = 101:109, id2 = c(NA, 101L, 102L, 103L, NA,
NA, NA, 107L, NA), date = c("01.1.2021", "12.1.2021", "17.1.2021",
"18.1.2021", "25.1.2021", "03.1.2021", "10.1.2021", "11.1.2021",
"09.1.2021")), class = "data.frame", row.names = c(NA, -9L))