Reputation: 10133
I have such a list:
df1 <- data.frame(var1 = 1:5, var2 = 6:10)
rownames(df1) <- 2001:2005
df2 <- data.frame(var5 = 21:25, var6 = 26:30)
rownames(df2) <- 2006:2010
mylist <- list(df1,df2)
> mylist
[[1]]
var1 var2
2001 1 6
2002 2 7
2003 3 8
2004 4 9
2005 5 10
[[2]]
var5 var6
2006 21 26
2007 22 27
2008 23 28
2009 24 29
2010 25 30
How can I convert each column within each data frame to a time series where start and end are given by min and max of the rownames of the respective data frame?
I tried:
lapply(mylist, function(x) {apply(x, 2, function(y) ts(y, start = min(rownames(y), end = max(rownames(y)))))})
resulting in:
Error in if (nobs != ndata) data <- if (NCOL(data) == 1) { :
missing value where TRUE/FALSE needed
but fail to make any sense of that.
Upvotes: 1
Views: 1575
Reputation: 887118
We can do this by looping columns using lapply
instead of apply
as the output of apply
is a matrix
and all the class gets lost. In addition, min/max
works on numeric/integer
elements, so it is advisable to convert the character
class of row.names
to numeric
lst1 <- lapply(mylist, function(x) lapply(x, function(y) ts(y,
start = min(as.numeric(row.names(x))), end = max(as.numeric(row.names(x))))))
lst1[[1]][[1]]
#Time Series:
#Start = 2001
#End = 2005
#Frequency = 1
#[1] 1 2 3 4 5
If we need to create ts
as columns, then assign the output back to the data.frame to keep the structure as before
lst2 <- lapply(mylist, function(x) {
x[] <- lapply(x, function(y) ts(y, start = min(as.numeric(row.names(x))),
end = max(as.numeric(row.names(x)))))
x})
str(lst2)
#List of 2
#$ :'data.frame': 5 obs. of 2 variables:
# ..$ var1: Time-Series [1:5] from 2001 to 2005: 1 2 3 4 5
# ..$ var2: Time-Series [1:5] from 2001 to 2005: 6 7 8 9 10
#$ :'data.frame': 5 obs. of 2 variables:
# ..$ var5: Time-Series [1:5] from 2006 to 2010: 21 22 23 24 25
# ..$ var6: Time-Series [1:5] from 2006 to 2010: 26 27 28 29 30
Upvotes: 3