Yi Wen Edwin Ang
Yi Wen Edwin Ang

Reputation: 55

R - unlist nested list of dates

I have the below nested list of dates. I would need to unlist and then to get unique list of dates starting from the earliest date to the latest date.

> str(datetemp)
List of 3
 $ FCX : Date[1:5747], format: "1995-07-10" "1995-07-11" "1995-07-12" "1995-07-13" ...
 $ MAT : Date[1:9164], format: "1982-01-04" "1982-01-05" "1982-01-06" "1982-01-07" ...
 $ MSFT: Date[1:8104], format: "1986-03-13" "1986-03-14" "1986-03-17" "1986-03-18" ...

The below strip the date class and return a list of numeric.

datetemp <- sort(unique(unlist(datetemp)))

I googled and read that unlist will strip the date class and return as numeric and some examples show do.call on a list of dates.

I am new to R and would appreciate if anyone could show me how I can apply do.call to nested list to get the required output.

Thank you.

Upvotes: 1

Views: 1061

Answers (2)

alistaire
alistaire

Reputation: 43354

One option is to coerce back to the Date class after unlist drops it. To do so, you'll need to specify the origin from which the integers are counted, which is the Unix epoch, i.e. 1970-01-01.

datetemp <- list(FCX = structure(c(9321, 9322, 9323, 9324), class = "Date"), 
                 MAT = structure(c(4386, 4387, 4388, 4389), class = "Date"), 
                 MSFT = structure(c(5915, 5916, 5919, 5920), class = "Date"))

datetemp2 <- as.Date(unlist(datetemp), origin = "1970-01-01")
datetemp2
#>         FCX1         FCX2         FCX3         FCX4         MAT1 
#> "1995-07-10" "1995-07-11" "1995-07-12" "1995-07-13" "1982-01-04" 
#>         MAT2         MAT3         MAT4        MSFT1        MSFT2 
#> "1982-01-05" "1982-01-06" "1982-01-07" "1986-03-13" "1986-03-14" 
#>        MSFT3        MSFT4 
#> "1986-03-17" "1986-03-18"

A better approach is to use do.call, which splices a list in as the parameters of a call and evaluates it, so if you use do.call(c, list(1, 2)), it effectively calls c(1, 2).

datetemp3 <- do.call(c, datetemp)
datetemp3
#>         FCX1         FCX2         FCX3         FCX4         MAT1 
#> "1995-07-10" "1995-07-11" "1995-07-12" "1995-07-13" "1982-01-04" 
#>         MAT2         MAT3         MAT4        MSFT1        MSFT2 
#> "1982-01-05" "1982-01-06" "1982-01-07" "1986-03-13" "1986-03-14" 
#>        MSFT3        MSFT4 
#> "1986-03-17" "1986-03-18"

Sorting and dropping duplicates drops names, which is probably good:

unique(sort(datetemp3))
#>  [1] "1982-01-04" "1982-01-05" "1982-01-06" "1982-01-07" "1986-03-13"
#>  [6] "1986-03-14" "1986-03-17" "1986-03-18" "1995-07-10" "1995-07-11"
#> [11] "1995-07-12" "1995-07-13"

Upvotes: 3

AkselA
AkselA

Reputation: 8846

You can flatten the list with do.call(c, ...), while keeping the date type.

ll <- lapply(7:9, function(x) as.Date(sample(7000:7020, x), origin="1970-01-01"))

unique(do.call(c, ll))

Upvotes: 2

Related Questions