2017-03-13 4 views
0

R 그룹의 첫 번째 행을 다시 코딩 할 수있는 방법을 이해하려고합니다. 그룹을 잡는 방법을 이해했으며 빠른 ifelse 문을 사용하여이 작업을 수행 할 수 있다고 생각했지만이 오류가 다가오고 있다고 생각합니다. 내가 최종 제품을 찾고R에서 각 그룹의 첫 번째 행을 다시 코드화 하시겠습니까?

library(data.table) 


latemail <- function(N, st="2012/01/01", et="2012/02/01") { 
    st <- as.POSIXct(as.Date(st)) 
    et <- as.POSIXct(as.Date(et)) 
    dt <- as.numeric(difftime(et,st,unit="sec")) 
    ev <- sort(runif(N, 0, dt)) 
    rt <- st + ev 

} 

#create our data frame 
set.seed(42) 
dt = latemail(20) 
work = setDT(as.data.frame(dt)) 
work[,worker:= stringi::stri_rand_strings(2, 5)] 
work[,dt:= as.POSIXct(as.character(work$dt), tz = "GMT")] 
work[,status:=NA] 

#order 
setorder(work, worker, dt) 

#add work times 
work$status[5] = "end" 
work$status[10] = "end" 
work$status[15] = "end" 
work$status[20] = "end" 

은 본질적으로 노동자 그룹의 모든 첫 번째 행을 복용하고 그것이 conscutive "끝"후 모든 행뿐만 아니라, 시작 코딩과 같이하는 다음은 샘플입니다 :

   dt worker status 
1: 2012-01-04 23:11:31 VOuRp start 
2: 2012-01-09 15:53:16 VOuRp  NA 
3: 2012-01-15 02:56:45 VOuRp  NA 
4: 2012-01-16 21:12:26 VOuRp  NA 
5: 2012-01-20 16:27:31 VOuRp end 
6: 2012-01-22 15:34:05 VOuRp start 
7: 2012-01-23 15:01:18 VOuRp  NA 
8: 2012-01-29 03:36:56 VOuRp  NA 
9: 2012-01-29 20:11:02 VOuRp  NA 
10: 2012-01-31 02:48:01 VOuRp end 
11: 2012-01-04 10:24:38 u8zw5 start 
12: 2012-01-08 17:02:20 u8zw5  NA 
13: 2012-01-14 23:33:35 u8zw5  NA 
14: 2012-01-15 12:23:52 u8zw5  NA 
15: 2012-01-18 03:53:15 u8zw5 end 
16: 2012-01-21 03:48:08 u8zw5 start 
17: 2012-01-23 02:01:10 u8zw5  NA 
18: 2012-01-26 12:51:10 u8zw5  NA 
19: 2012-01-29 18:23:46 u8zw5  NA 
20: 2012-01-29 22:22:14 u8zw5 end 

데이터 테이블에서 어떻게 접근합니까?

답변

1

i 인수에서 일부 기본 R을 사용하여 행을 선택한 다음 :=을 사용하여 "시작"값을 지정할 수 있습니다.

work[c(1, head(which(status == "end" & !is.na(status)) + 1, -1)), status := "start"] 

여기에서 c(1, head(which(status == "end" & !is.na(status) + 1), -1))은 채울 위치가있는 정수의 벡터를 반환합니다. which은 "끝"과 일치하고 누락 된 값이 아닌 위치를 선택합니다. + 1은이 값을 증가시킵니다. head은 -1 인수를 사용하여 마지막 위치를 data.table 외부에 놓기 위해 사용됩니다.

이 반환

work 
        dt worker status 
1: 2012-01-04 23:11:31 VOuRp start 
2: 2012-01-09 15:53:16 VOuRp  NA 
3: 2012-01-15 02:56:45 VOuRp  NA 
4: 2012-01-16 21:12:26 VOuRp  NA 
5: 2012-01-20 16:27:31 VOuRp end 
6: 2012-01-22 15:34:05 VOuRp start 
7: 2012-01-23 15:01:18 VOuRp  NA 
8: 2012-01-29 03:36:56 VOuRp  NA 
9: 2012-01-29 20:11:02 VOuRp  NA 
10: 2012-01-31 02:48:01 VOuRp end 
11: 2012-01-04 10:24:38 u8zw5 start 
12: 2012-01-08 17:02:20 u8zw5  NA 
13: 2012-01-14 23:33:35 u8zw5  NA 
14: 2012-01-15 12:23:52 u8zw5  NA 
15: 2012-01-18 03:53:15 u8zw5 end 
16: 2012-01-21 03:48:08 u8zw5 start 
17: 2012-01-23 02:01:10 u8zw5  NA 
18: 2012-01-26 12:51:10 u8zw5  NA 
19: 2012-01-29 18:23:46 u8zw5  NA 
20: 2012-01-29 22:22:14 u8zw5 end 
+1

유사 아이디'작업을 추가 할 수 [, seq_id = cumsum (! .I == 1L | 변화 (is.na (상태) 상태 == "끝")) ] 및 다음에 'work [. (unique (seq_id)), on =. (seq_id), mult = "first", status : = "start"]'와 유사합니다. http://stackoverflow.com/q/42683815/ – Frank

+0

이것은이 문제에 대한 중장비이지만,'mult' 인수의 사용법은 깔끔합니다. – lmo

+0

그래, cumsum - 이동은 무겁지 않아 나는 OP의 데이터를 구성하는 데 필요한 주장하고 싶습니다. 내 눈에는 c (1, head (x + 1, -1))보다 더 쉽게 따라 할 수 있습니다. mult *와 결합하면 * 무거운 구문이지만,이 상태 표시는 어쨌든 실수입니다. – Frank

관련 문제