R sapply vs apply vs lapply + as.data.frame

scr*_*Owl 0 r date apply plyr lapply

我正在使用一些Date列并尝试清理显然不正确的日期.我用这里safe.ifelse提到的函数编写了一个函数.

这是我的玩具数据集:

df1 <- data.frame(id = 1:25
    , month1 = seq(as.Date('2012-01-01'), as.Date('2014-01-01'), by = 'month'  )
    , month2 = seq(as.Date('2012-01-01'), as.Date('2014-01-01'), by = 'month'  )
    , month3 = seq(as.Date('2012-01-01'), as.Date('2014-01-01'), by = 'month'  )
    , letter1 = letters[1:25]
    )
Run Code Online (Sandbox Code Playgroud)

这适用于单个列:

df1$month1 <- safe.ifelse(df1$month1 > as.Date('2013-10-01'), as.Date('2013-10-01'), df1$month1)
Run Code Online (Sandbox Code Playgroud)

由于我有多个列,我想使用一个函数并应用于立即处理所有Date列:

capDate <- function(x){
today1 <- Sys.Date()
    safe.ifelse <- function(cond, yes, no){ class.y <- class(yes)
                                  X <- ifelse(cond,yes,no)
                                  class(X) <-class.y; return(X)}

    x <- safe.ifelse(as.Date(x) > as.Date(today1), as.Date(today1), as.Date(x))
 }
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用时 sapply()

df1[,dateCols1] <- sapply(df1[,dateCols1], capDate)
Run Code Online (Sandbox Code Playgroud)

要么 apply()

df1[,dateCols1] <- apply(df1[,dateCols1],2, capDate))
Run Code Online (Sandbox Code Playgroud)

Date列失去其Date格式.我发现解决这个问题的唯一方法是使用lapply()然后转换回来data.frame().有谁能解释一下?

df1[,dateCols1] <- as.data.frame(lapply(df1[,dateCols1], capDate))
Run Code Online (Sandbox Code Playgroud)

Ric*_*ton 7

无论sapplyapply结果转化为矩阵. as.data.frame(lapply(...))循环数据框列是一种安全的方法.

as.data.frame(
  lapply(
    df1, 
    function(column) 
    {
      if(inherits(column, "Date")) 
      {
        pmin(column, Sys.Date())
      } else column
    }
  )
)
Run Code Online (Sandbox Code Playgroud)

这是一个小吸尘器ddplyplyr.

library(plyr)
ddply(
  df1, 
  .(id), 
  colwise(
    function(column) 
    {
      if(inherits(column, "Date")) 
      { 
        pmin(column, Sys.Date()) 
      } else column
    }
  )
)
Run Code Online (Sandbox Code Playgroud)

  • +1让我读"as.data.frame"意识到你不需要`do.call(data.frame,...)` (2认同)