using purrr to affect single columns of each dataf

2019-06-20 08:44发布

still getting used to purrr and I have one of those questions that I think should be easy, but I don't know how to do it. All I want to do is convert the datetimes in the below, to dates with as.Date(). it's a list of dataframes. Been playing around but haven't found something that works yet... any help appreciated.

df <- data.frame(Date = seq.POSIXt(Sys.time(), Sys.time() + hours(24), by = "hour"),
             useless = "ignore me")
df2 <- data.frame(Date = seq.POSIXt(Sys.time(), Sys.time() + hours(1), by = "min"),
                    useless = "ignore me")
mylist <- list(df,df2)
mylist %<>% map(?????)

2条回答
Emotional °昔
2楼-- · 2019-06-20 09:19

You can combine map() with mutate() from the dplyr package (also tidyverse). map() can be used to apply mutate() each data frame in your list. mutate() can apply as.Date() to the Date column. You'd write it like this:

map(mylist, mutate, Date = as.Date(Date))

This line is saying:

  • map()/apply the mutate() function to each object in mylist
  • Each time mutate() is applied to an object, do it as if you were writing mutate(object, Date = as.Date(Date))

Full code:

library(lubridate)
library(purrr)
library(dplyr)

df <- data.frame(Date = seq.POSIXt(Sys.time(), Sys.time() + hours(24), by = "hour"),
                 useless = "ignore me")
df2 <- data.frame(Date = seq.POSIXt(Sys.time(), Sys.time() + hours(1), by = "min"),
                  useless = "ignore me")
mylist <- list(df,df2)
mylist <- map(mylist, mutate, Date = as.Date(Date))
查看更多
在下西门庆
3楼-- · 2019-06-20 09:43

The canonical way to achieve your goal would be to combine map with some verb from dplyr, like mutate_at. Currently purrr still has the function dmap_at, but it will be removed from purrr in the future.

Hence, you would map over your list, and then modify the date column with mutate_at:

library(purrr)
library(lubridate)
library(dplyr)

mylist %>%
  map(~mutate_at(.x, "Date", as.Date))

You could also use at_depth, which in the case of at_depth(1, ...) is equal to map and is therefore not necessary:

mylist %>%
  at_depth(1, ~mutate_at(.x, "Date", as.Date))

The original approach, staying within purrr, was to use dmap_at:

mylist %>%
  map(~dmap_at(.x, "Date", as.Date))

But since we now have mutate_at and mutate_all and friends, it is recommended to use them instead of dmap, dmap_at and so forth.

Data

df <- data.frame(Date = seq.POSIXt(Sys.time(), Sys.time() + hours(24), by = "hour"),
                 useless = "ignore me")
df2 <- data.frame(Date = seq.POSIXt(Sys.time(), Sys.time() + hours(1), by = "min"),
                  useless = "ignore me")
mylist <- list(df,df2)
查看更多
登录 后发表回答