2014-12-19 6 views
2

dcast 큰 데이터 세트 (수백만 행)로 변환하려고합니다. 나는 도착 시간과 출발지에 대해 하나의 행을 가지고 있고, 출발 시간과 목적지에 대해서는 또 다른 행을 가지고있다. 두 경우 모두 단위를 식별하기 위해 id이 있습니다. 그것은이 유사하게 나타납니다다중 변수를 사용하여 효율적으로 큰 데이터 세트를

id time   movement origin dest 
1 10/06/2011 15:54 ARR  15 15 
1 10/06/2011 16:14 DEP  15 29 
2 10/06/2011 17:59 ARR  73 73 
2 10/06/2011 18:10 DEP  73 75 
2 10/06/2011 21:10 ARR  75 75 
2 10/06/2011 21:20 DEP  75 73 
3 10/06/2011 17:14 ARR  17 17 
3 10/06/2011 18:01 DEP  17 48 
4 10/06/2011 17:14 ARR  49 49 
4 10/06/2011 17:26 DEP  49 15 

그래서, 쌍 (ARR - DEP)를 재 할당 싶습니다 (here로) 효율적으로이 작업을 수행. 매우 큰 데이터 세트이므로 for loop은이 경우 작동하지 않습니다. 이상적인 출력 될 것

index unitid origin arr time dest dep time 
    1 1  15 10/06/2011 14:33 29 10/06/2011 19:24 
    2 2  73 10/06/2011 14:59 75 10/06/2011 17:23 
    3 2  75 10/06/2011 21:10 73 10/06/2011 23:40 

데이터 : 데이터 집합이 예에서와 같이 구성되어있는 경우

 df <- structure(list(time = structure(c(7L, 16L, 8L, 11L, 18L, 20L, 
10L, 12L, 3L, 6L, 15L, 19L, 9L, 4L, 5L, 14L, 1L, 2L, 13L, 17L 
), .Label = c("10/06/2011 09:08", "10/06/2011 10:54", "10/06/2011 11:38", 
"10/06/2011 12:41", "10/06/2011 12:54", "10/06/2011 14:26", "10/06/2011 14:33", 
"10/06/2011 14:59", "10/06/2011 17:12", "10/06/2011 17:14", "10/06/2011 17:23", 
"10/06/2011 18:56", "10/06/2011 19:03", "10/06/2011 19:04", "10/06/2011 19:16", 
"10/06/2011 19:24", "10/06/2011 20:12", "10/06/2011 21:10", "10/06/2011 22:28", 
"10/06/2011 23:40"), class = "factor"), movement = structure(c(1L, 
2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 3L, 1L, 2L, 2L, 1L, 
2L, 2L, 3L), .Label = c("ARR", "DEP", "ITZ"), class = "factor"), 
    origin = c(15L, 15L, 73L, 73L, 75L, 75L, 17L, 17L, 49L, 49L, 
    15L, 15L, 32L, 10L, 10L, 17L, 76L, 76L, 76L, 76L), dest = c(15L, 
    29L, 73L, 75L, 75L, 73L, 17L, 48L, 49L, 15L, 15L, 49L, 32L, 
    10L, 17L, 10L, 76L, 65L, 76L, 65L), id = c(1L, 1L, 2L, 2L, 
    2L, 2L, 3L, 3L, 4L, 4L, 4L, 4L, 5L, 6L, 6L, 6L, 7L, 7L, 8L, 
    8L)), .Names = c("time", "movement", "origin", "dest", "id" 
), row.names = c(NA, -20L), class = "data.frame") 
+0

은 아마 당신이에서'dcast.data.table'을 시도 할 수 있었다 ([의 1.9.8 지점 "data.table"] https://github.com/Rdatatable/data.table/tree/1.9.8) (그러나 CRAN 버전이 아니기 때문에 상황이 바뀔 수도 있습니다.) – A5C1D2H2I1M1N2O1R2T1

+0

안녕하세요 @AnandaMahto, 이 코드는 (@akron에 의해) dcast.data.table (setDT (df) [, c ('. id', 'Seq')] : = list (c '도착', '출발' id + Seq ~ .id, value.var = 'time')'그러나 원점과 원점을 더하고 싶으면 (예 : gl (.N, 2, .N))] tination 정보, 나는 그것을 모으는 법을 정말로 모른다. 그것이 매우 큰 데이터 세트 (수백만 줄)임을 염두에 두십시오. – user3507584

+0

당신은 얼마나 많은 수백만 행을 다루고 있습니까? – Arun

답변

3

어때? data.table 사용 : 대신 각 그룹에 !grp을하고 그 열을 값 !grp와 다른 열을 추가하고 사용하는 경우는 약간 빠른이 할 수

require(data.table) 
setorder(setDT(df), id, time) 
df[, grp := FALSE][movement == "ARR", grp := TRUE] 
df[, .(time[grp], time[!grp], origin[grp], dest[!grp]), by=id] 
# id     V1     V2 V3 V4 
# 1: 1 10/06/2011 14:33:57 10/06/2011 19:24:16 15 29 
# 2: 2 10/06/2011 14:59:14 10/06/2011 17:23:20 73 75 
# 3: 2 10/06/2011 21:10:56 10/06/2011 23:40:29 75 73 
# 4: 3 10/06/2011 17:14:44 10/06/2011 18:56:39 17 48 
# 5: 4 10/06/2011 11:38:43 10/06/2011 14:26:43 49 15 
# 6: 4 10/06/2011 19:16:55 10/06/2011 22:28:14 15 49 
# 7: 5 10/06/2011 10:41:20 10/06/2011 12:54:26 10 17 
# 8: 6 10/06/2011 09:08:05 10/06/2011 10:54:48 76 65 

.


이 작동하는 방법 :

  • setDT은 참조 data.table에 data.frame 변환합니다.

  • setorder은 제공되는 열 (및 순서)을 기준으로 data.table을 다시 정렬합니다. 여기서는 idtime 열을 기준으로 df의 행을 큰 순서로 다시 정렬합니다.

  • 은 그 다음 사용 data.table의 TRUEmovement == "ARR"movement == "DEP"FALSE 보유 추가 열을 추가함으로써 기준 서브 할당.

    참고 : df$movement 열의 요인 수준에는 ITZ이라는 추가 수준이 있으며이 샘플 데이터에는없는 것 같습니다. 어떻게 처리해야할지 모르겠다.

  • origin과 1,2,6,6 ... 요소를 dest (그리고 마찬가지로 time)의 1,3,5, .. 요소를 선택하면됩니다.

이 한 ARR 시간 (매우 유효한 가정이다) DEP 시간 전에 항상 작동합니다.데이터 불일치와 Q에 영업 이익의 편집에 따라


:

na.omit(df[movement != "ITZ", .(time[grp], time[!grp], origin[grp], dest[!grp]), by=id]) 
+1

'setorder (setDT (df), id, time)'에 대한 시간이 620 만 행. df [, grp : = FALSE] [움직임 == ARR, grp : = TRUE]'0.53 초, df [시간 (grp), 시간 [! grp], 원점 [grp] dest [! grp]), by = id]'6.52 초. 총 7.3 초이므로 거의 초당 900 만 개의 행이 처리됩니다. 고마워요. @ Arun – user3507584

+1

@Arun 이것은 훌륭한 해결책입니다. – akrun

1

, 하나의 도착과 ID와 기원 당 하나의 출발 시간이 즉, 당신은 할 수 있습니다 이 작업을 수동으로 수행하려면 데이터 순서를 변경하고 하위 집합을 지정하십시오. 물론이 작업을 매우 신중하게해야하며 가능한 한 많은 수표를 추가하여 오류를 잡으십시오.

dat <- df[order(df$id, df$origin, df$dest, df$movement), ] 
dat.dep <- dat[dat$movement == "DEP", ] 
dat.arr <- dat[dat$movement == "ARR", ] 
stopifnot(nrow(dat.dep) == nrow(dat.arr) & 
    dat.dep$origin == dat.arr$origin & 
    dat.dep$id == dat.arr$id) 
result <- dat.dep[c("id", "origin", "dest")] 
result$arr.time <- dat.arr$time 
result$dep.time <- dat.dep$time 
result 
# id origin dest   arr.time   dep.time 
# 2 1  15 29 10/06/2011 14:33:57 10/06/2011 19:24:16 
# 4 2  73 75 10/06/2011 14:59:14 10/06/2011 17:23:20 
# 6 2  75 73 10/06/2011 21:10:56 10/06/2011 23:40:29 
# 8 3  17 48 10/06/2011 17:14:44 10/06/2011 18:56:39 
# 12 4  15 49 10/06/2011 19:16:55 10/06/2011 22:28:14 
# 10 4  49 15 10/06/2011 11:38:43 10/06/2011 14:26:43 
# 14 5  10 17 10/06/2011 10:41:20 10/06/2011 12:54:26 
# 16 6  76 65 10/06/2011 09:08:05 10/06/2011 10:54:48 
+0

@Arun 나는 그것을 이해한다. 모든 데이터 요소가 고유 ID, 원점 및 이동으로 고유하게 결정되지는 않습니까? – konvas

+1

@Arun aaah 이제 알겠습니다. 그래서 문제는 제가 말한 것이 었습니다. 나는 해결책에서 이것을 가정하지 않았다. 나는 ID와 기원별로 하나의 도착과 출발을 의미했다. 감사 : – konvas

관련 문제