简体   繁体   中英

Apply date format in multiple dataframes

I have 3 data frames, as shown in the code below.

code_1000 <-
  as.data.frame(cbind(
    c("3", "3", "7", "7", "7", "7", "2", "2", "4", "4"),
    c("344", "344", "73", "73", "71", "72", "21", "27", "42", "43"),
    c("9-02-2017", "10-01-2016","9-02-2014", "25-03-2015", "9-02-2017",
      "10-06-2017", "8-04-2017", "25-08-2016", "07-08-2017", "15-11-2016"
    )
  ))
code_2430 <-
  as.data.frame(cbind(
    c("3", "3", "7", "7", "7", "7", "2", "2", "4", "4"),
    c("344", "344", "73", "73", "71", "72", "21", "27", "42", "43"),
    c("9-02-2017", "10-01-2016","9-02-2014", "25-03-2015", "9-02-2017",
      "10-06-2017", "8-04-2017", "25-08-2016", "07-08-2017", "23-09-2016"
    )
  ))
code_3453 <-
  as.data.frame(cbind(
    c("3", "3", "7", "7", "7", "7", "2", "2", "4", "4"),
    c("344", "344", "73", "73", "71", "72", "21", "27", "42", "43"),
    c("9-02-2017", "10-01-2016","9-02-2014", "25-03-2015", "9-02-2017",
      "10-06-2017", "8-04-2017", "25-08-2016", "07-08-2017", "13-06-2016"
    )
  ))
names(code_1000) <- c("number", "code", "date")
names(code_2430) <- c("number", "code", "date")
names(code_3453) <- c("number", "code", "date")

I want to apply a date format on the column date of each dataframe ( code_1000 , code_2430 and code_3453 ). The desired date format is:

   code_1000$date<-lubridate::dmy(as.character(code_1000$date)

Which gives a date format "yyyy-mm-dd" as output (see figure in the link below).

在此处输入图片说明

The code above shows 3 samples to make it simpler. Actually I have 50 dataframes, and I am using Shiny to plot some scatter graphs, which the x axis is the date column.

USing for , I tried the following code:

 list<- as.data.frame(c("1000","2430","3453"))
    names(list) <- c("code.ID") # list of the codes dataframes ID

    date.format<-function(df){
    lubridate::dmy(as.character(df[,"date"]))
    }  # function to apply the desired date format

    for (m in 1:nrow(list)){
      loop.df<-eval(parse(text=paste0("code_",list$code.ID[m]))) # for each m, it returns a code_xxxx date frame

    assign(loop.df[,3],date.format(loop.df)) # apply the date format on the dataframe, storing the results
    }

I got the following error:

Error in `[.default`(loop.df, , 3) : incorrect number of dimensions 

When I apply the isolated date.format function on the dateframes, it works fine.

I would like to learn how to do this using for and lapply() function, as I have read that in R lapply() is an easier approach most of times.

Thank you in advance!

<rant on> I've been trying to get people to abandon the as.data.frame(cbind(...)) strategy for years. It forces everything to be the same atomic type and then when that type happens to be character the results is all factors. A big mess in my opinion. In this case there is a dmy method for factors, but some authors have not provided for that typical user expectation <rant off> (Just use data.frame() .)

Assemble the items with the first 5 characters "code_" in a character vector and then loop over them to build a list. Then loop (with lapply again) over that list of R objects to convert the 3rd column to date format:

> objects(pattern="code_.+")
[1] "code_1000" "code_2430" "code_3453"
> obj_list <- lapply(objects(pattern="code_.+"), get)
> str(obj_list)
List of 3
 $ :'data.frame':   10 obs. of  3 variables:
  ..$ number: Factor w/ 4 levels "2","3","4","7": 2 2 4 4 4 4 1 1 3 3
  ..$ code  : Factor w/ 8 levels "21","27","344",..: 3 3 8 8 6 7 1 2 4 5
  ..$ date  : Factor w/ 9 levels "07-08-2017","10-01-2016",..: 9 2 8 5 9 3 7 6 1 4
 $ :'data.frame':   10 obs. of  3 variables:
  ..$ number: Factor w/ 4 levels "2","3","4","7": 2 2 4 4 4 4 1 1 3 3
  ..$ code  : Factor w/ 8 levels "21","27","344",..: 3 3 8 8 6 7 1 2 4 5
  ..$ date  : Factor w/ 9 levels "07-08-2017","10-01-2016",..: 9 2 8 5 9 3 7 6 1 4
 $ :'data.frame':   10 obs. of  3 variables:
  ..$ number: Factor w/ 4 levels "2","3","4","7": 2 2 4 4 4 4 1 1 3 3
  ..$ code  : Factor w/ 8 levels "21","27","344",..: 3 3 8 8 6 7 1 2 4 5
  ..$ date  : Factor w/ 9 levels "07-08-2017","10-01-2016",..: 9 2 8 5 9 3 7 6 1 4

> obj_list <- lapply(obj_list , function(dfrm) {                  
                      dfrm[[3]] <- lubridate::dmy(as.character(dfrm[,"date"]))
                      dfrm} )
> str(obj_list)
List of 3
 $ :'data.frame':   10 obs. of  3 variables:
  ..$ number: Factor w/ 4 levels "2","3","4","7": 2 2 4 4 4 4 1 1 3 3
  ..$ code  : Factor w/ 8 levels "21","27","344",..: 3 3 8 8 6 7 1 2 4 5
  ..$ date  : Date[1:10], format: "2017-02-09" "2016-01-10" ...
 $ :'data.frame':   10 obs. of  3 variables:
  ..$ number: Factor w/ 4 levels "2","3","4","7": 2 2 4 4 4 4 1 1 3 3
  ..$ code  : Factor w/ 8 levels "21","27","344",..: 3 3 8 8 6 7 1 2 4 5
  ..$ date  : Date[1:10], format: "2017-02-09" "2016-01-10" ...
 $ :'data.frame':   10 obs. of  3 variables:
  ..$ number: Factor w/ 4 levels "2","3","4","7": 2 2 4 4 4 4 1 1 3 3
  ..$ code  : Factor w/ 8 levels "21","27","344",..: 3 3 8 8 6 7 1 2 4 5
  ..$ date  : Date[1:10], format: "2017-02-09" "2016-01-10" ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM