1
votes

I have to admit I'm totally stumped on this one, so apologies for no clear attempt, though hopefully I can ask the question clearly:

I have a list of dataframes. For all of them, there are multiple date-type variables that need to be formatted as a date (e.g., as.Date(data$var, format = "%m/%d/%y")).

The problem is that the date variable is named something different in each of the dataframes. In the example below, we've got "start_date" and "end_date".

Is there a way to write some function that operates over the variable names in a dataframe and if it finds text that contains "date", will do the formatting operation?

The dataframes:

west <- data.frame(
    spend = sample(50:100,50,replace=T),
    trials = sample(100:200,50,replace=T),
    start_date = sample(c("06/07/14","06/08/14","06/09/14"), 50, replace=T),
    country = sample(c("usa","canada","uk"),50,replace = T)
    )

east <- data.frame(
    end_date = sample(c("06/07/14","06/08/14","06/09/14"), 50, replace=T),
    spend = sample(50:100,50,replace=T),
    trials = sample(100:200,50,replace=T),
    country = sample(c("china","japan","skorea"),50,replace = T)
    )

And turning them into a list (in reality, this is a much larger list):

combined <- c(west,east)

How could I take the logical vector from a grepl statement and tell it to operate on the variable where that logical vector is "TRUE" across the list elements?

grepl("date", names(combined))

[1] FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE
1
You can create a list list(west, east) and apply grepl on that list. - akrun
@akrun It's true that the OP can create a list (and indeed should, rather than c(west, east), which is not a list of data frames), but applying grepl on that list won't work. - David Robinson
Yep. I'd suggest posting that as an answer. - David Robinson

1 Answers

2
votes

Try

lst1 <- lapply(list(west, east), function(x) {
            indx <- grepl("date", names(x))
            x[,indx] <- as.Date(x[,indx], format="%m/%d/%y")
            x
      })

In case you need to update the individual objects ie. east, west etc. (which is not needed because most of the operations including saving it to file with write.csv/write.table can be done within list using lapply)

list2env(setNames(lst1, c("west", "east")), envir=.GlobalEnv) 

Update

If there are multiple variables with date

east <- data.frame( end_date = sample(c("06/07/14","06/08/14","06/09/14"), 50,
replace=T), new_date = sample(c("06/07/14","06/12/14","06/09/14"), 50,
replace=T),    spend = sample(50:100,50,replace=T), trials = 
sample(100:200,50,replace=T), country =
sample(c("china","japan","skorea"),50,replace = T)) 


lst2 <- lapply(list(west, east), function(x) {
                 indx <- grepl("date", names(x))
                 x[,indx] <- lapply(x[,indx,drop=FALSE], as.Date, format="%m/%d/%y")
                  x})

 lapply(lst2, head,2)
 #[[1]]
 #    spend trials start_date country
 #1    83    188 2014-06-09     usa
 #2    83    107 2014-06-08     usa

 #[[2]]
 #   end_date   new_date spend trials country
 #1 2014-06-08 2014-06-12    53    144   china
 #2 2014-06-08 2014-06-09   100    118   china