2016-07-18 2 views
2

주어진 날짜의주의 첫날을 찾는 함수가 있습니다. 이 특별한 문제에서 목요일에 시작되는 주.중지 날짜를 숫자로 변환하는 중

이 기능은 개별 날짜에 적합합니다.

week_commencing <- function(date) { 
    weekday <- lubridate::wday(date) 
    if (weekday >= 5) { 
    return(date - lubridate::days(weekday) + lubridate::days(5)) 
    } else { 
    return(date - lubridate::days(weekday) - lubridate::days(2)) 
    } 
} 

이제는 dplyr 파이프를 사용하고 싶습니다. 그래서 Map 열을 허용하도록 수정했습니다.

week_commencing <- function(dates) { 
    Map(function(date) { 
    weekday <- lubridate::wday(date) 
    if (weekday >= 5) { 
     return(date - lubridate::days(weekday) + lubridate::days(5)) 
    } else { 
     return(date - lubridate::days(weekday) - lubridate::days(2)) 
    } 
    },dates) 
} 

나는이 함수가 작동한다고 생각하지만 숫자 날짜로 끝나기 때문에 날짜에 이상한 강압을 적용하고 있습니다.

> test <- data.frame(datetime=seq.Date(as.Date("2016-06-01"),as.Date("2016-06-10"), by='day')) 
> test 
    datetime 
1 2016-06-01 
2 2016-06-02 
3 2016-06-03 
4 2016-06-04 
5 2016-06-05 
6 2016-06-06 
7 2016-06-07 
8 2016-06-08 
9 2016-06-09 
10 2016-06-10 

> test %>% mutate(datetime=week_commencing(datetime)) 
    datetime 
1  16947 
2  16954 
3  16954 
4  16954 
5  16954 
6  16954 
7  16954 
8  16954 
9  16961 
10 16961 

정상적인 날짜 개체로 끝내는 방법에 대한 아이디어가 있으십니까? 지도가 항상 강압을 적용합니까?

답변

3

여기에 class 속성이 드롭 된 이유를 알지 못합니다 (다른 * 적용 기능을 사용할 때도 마찬가지입니다). - 문제는, 깊은, unlist 클래스 떨어질 것 같다 :

> unlist(list(structure(1, class = 'foo'))) 
[1] 1 

을하지만 수정은 충분히 간단하다 : 마지막에 클래스를 설정합니다.

또한 Map (list을 반환 함)을 사용하지 말고 vapply을 사용하는 것이 좋습니다. 또한 기능에 Vectorize를 사용할 수

week_commencing <- function(dates) { 
    wc <- function(date) { 
    weekday <- lubridate::wday(date) 
    if (weekday >= 5) { 
     return(date - lubridate::days(weekday) + lubridate::days(5)) 
    } else { 
     return(date - lubridate::days(weekday) - lubridate::days(2)) 
    } 
    } 

    structure(vapply(dates, wc, numeric(1)), class = 'Date') 
} 

, 그러나 그것은 또한 class 속성을 제거합니다 그럼 우리는 남아 있습니다.

+0

감사합니다 많이! 이것은 매력처럼 작동합니다! 'class <-' (16947,'Date ') 같은 구문을 본 적이 없습니다 ... 이름이 있습니까? 특히'class <-'부분은 내가 그것에 대해 읽을 수 있도록? – xav

+2

'\'class <- \'(...)'대신에'struct (vapply (dates, wc, numeric (1)), class = "Date")'를 사용할 수도 있습니다. – nrussell

+0

@xav 클래스의 [대체 함수] (http://stackoverflow.com/q/11563154/1968)를 호출합니다. 나는이 문법을 사용하여 값을 유지하는 데 쓸모없는 변수를 만드는 것을 피하기 위해 연결 응답의 설명에서 변경하고자하는 한 가지는 함수 이름에 문자열을 사용하지 않아야한다는 것이다. [backtick quoting 대신 사용하십시오] (http://stackoverflow.com/a/36229703/1968), 내 답변에). 그러나, 나는 (구조화 된) 구조체를 사용할 수 있다는 것을 잊어 버렸습니다. –

2

또는, dplyr 가족에 보관 수 :

week_commencing <- function(date) { 
    weekday <- lubridate::wday(date) 
    dplyr::if_else(weekday >= 5, 
       date - lubridate::days(weekday) + lubridate::days(5), 
       date - lubridate::days(weekday) - lubridate::days(2)) 
} 
+0

나는 Konrad의 대답의 유연성을 선호하지만 실제로는 900k 행의 데이터 세트에서 몇 초 만에 실행되므로 다른 솔루션은 1 시간 후에도 처리되기 때문에 실제로는 현재 사용하고 싶습니다. 고마워요! – xav