2013-10-22 97 views
0

我正在處理一些Date列,並試圖清理明顯不正確的日期。我已經使用safe.ifelse功能here編寫了一個函數。R sapply vs apply lapply + as.data.frame

這裏是我的玩具數據集:

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)) 
+0

兩者都轉換爲矩陣或數組。使用'lapply',然後對結果使用'do.call(data.frame,output)'。 –

回答

7

兩個sapplyapply結果轉換爲矩陣。 as.data.frame(lapply(...))是循環數據幀列的安全方式。

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

這是一個小吸塵器ddplyplyr

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

+1讓我讀'as.data.frame'來實現你不需要'do.call(data.frame,...)' –