2013-10-22 2 views
0

일부 Date 열과 함께 작업하고 있으며 분명히 잘못된 날짜를 정화하려고합니다. 나는 here을 언급 한 safe.ifelse 함수를 사용하여 함수를 작성했다.R sapply vs 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)) 
} 

을 내가을 사용하려고하지만 경우

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 
    } 
) 
) 

그것은 plyr에서 ddply와 약간의 청소기입니다 .

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

+1은'do.call (data.frame, ...)'이 필요 없다는 것을 깨닫기 위해'as.data.frame'을 읽게합니다. –