【问题标题】:R sapply vs apply vs lapply + as.data.frameR sapply vs apply vs lapply + as.data.frame
【发布时间】:2013-10-31 04:40:37
【问题描述】:

我正在处理一些 Date 列,并试图清除明显不正确的日期。我使用here 中提到的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]
    )

这适用于单列:

df1$month1 <- safe.ifelse(df1$month1 > as.Date('2013-10-01'), as.Date('2013-10-01'), df1$month1)

由于我有多个列,我想使用一个函数并申请一次处理所有 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))
 }

但是当我尝试使用sapply()

df1[,dateCols1] <- sapply(df1[,dateCols1], capDate)

apply()

df1[,dateCols1] <- apply(df1[,dateCols1],2, capDate))

Date 列丢失了 Date 格式。我发现解决此问题的唯一方法是使用lapply(),然后转换回data.frame()。谁能解释一下?

df1[,dateCols1] <- as.data.frame(lapply(df1[,dateCols1], capDate))

【问题讨论】:

  • 都转换为矩阵或数组。在结果上使用lapply,然后使用do.call( data.frame , output )

标签: r date plyr apply lapply


【解决方案1】:

sapplyapply 都将结果转换为矩阵。 as.data.frame(lapply(...)) 是一种遍历数据框列的安全方式。

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

使用来自plyrddply 会更干净一些。

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

【讨论】:

  • +1 让我读到 as.data.frame 意识到你不需要 do.call( data.frame , ... )
猜你喜欢
  • 2017-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-20
  • 1970-01-01
  • 2015-06-05
相关资源
最近更新 更多