2016-09-09 2 views
2

데이터 집합의 다양한 하위 집합을 결합하는 여러 변수를 만들고 싶습니다. 내가 변수 Var1 여러 평균을 찾으려면다른 하위 집합에 대해 data.table의 j로 여러 개의 새로운 열을 만드는 방법

DT = data.table(Group1 = c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4), 
       Group2 = c(1,1,1,2,2,1,1,2,2,2,1,1,1,1,2,1,1,2,2,2), 
        Var1 = c(1,1,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0)) 

: 설명 예를 들어, 다음과 같은 데이터를 말한다. 내가 알고 싶은 :

  • mean(Var1)Group1

또는에서별로 그룹화, Group2 == 2있는 사람에 대해서만 Group1

  • mean(Var1)별로 그룹화, Group2 == 1있는 사람에 대해서만 Group1
  • mean(Var1)별로 그룹화 data.table 용어,

    DT[, mean(Var1), by=Group1] 
    DT[Group2==1, mean(Var1), by=Group1] 
    DT[Group2==2, mean(Var1), by=Group1] 
    

    분명히 이들 중 하나를 계산하는 것은 매우 간단합니다. 그러나 나는 그들 모두가 i에서 다른 부분 집합을 사용하기 때문에 3 가지를 모두 계산할 좋은 방법을 찾을 수 없습니다. 지금까지 사용해온 솔루션은 개별적으로 생성 한 다음이를 통합 테이블에 병합합니다.

    DT_all <- DT[, .(avgVar1_all = mean(Var1)), by = Group1] 
    DT_1 <- DT[Group2 == 1, .(avgVar1_1 = mean(Var1)), by = Group1] 
    DT_2 <- DT[Group2 == 2, .(avgVar1_2 = mean(Var1)), by = Group1] 
    group_info <- merge(DT_all, DT_1, by = "Group1") 
    group_info <- merge(group_info, DT_2, by = "Group1") 
    
    group_info 
    # Group1 avgVar1_all avgVar1_1 avgVar1_2 
    # 1:  1   0.4 0.6666667 0.0000000 
    # 2:  2   0.6 1.0000000 0.3333333 
    # 3:  3   0.2 0.2500000 0.0000000 
    # 4:  4   0.0 0.0000000 0.0000000 
    

    내가 사용할 수있는보다 우아한 방법이 있습니까?

  • 답변

    5

    그냥 하나의 그룹 작업이 .SD를 사용하여 모든 것을 할 : 당신은 reshape2::dcast을 사용할 수 있습니다

    DT[, .(
         all = mean(Var1), 
         grp1 = .SD[Group2==1, mean(Var1)], 
         grp2 = .SD[Group2==2, mean(Var1)] 
        ), 
        by = Group1, 
        .SDcols=c("Group2","Var1") 
        ] 
    
    # Group1 all  grp1  grp2 
    #1:  1 0.4 0.6666667 0.0000000 
    #2:  2 0.6 1.0000000 0.3333333 
    #3:  3 0.2 0.2500000 0.0000000 
    #4:  4 0.0 0.0000000 0.0000000 
    
    +0

    성능을 위해, 일반적으로 눈살을 찌푸리게 .SD을 부분 집합은 아니지만이, 트릭을합니까? 또는 .SD에서 열의 하위 집합을 가져 오는 것입니까? –

    +1

    @ConnorJ - 나는 주제에 대한 권위자는 아니지만'.SD' 하위 집합은 많은 문제에있어 최적화 된 것으로 생각됩니다. 내가 틀렸다면 Arun이나 Matt이 머리를 맞아서 기쁘게 생각합니다. – thelatemail

    +0

    @ConnorJ - 이제 세부 정보를 살펴 보았으니 어쩌면 네 말이 맞고 이상하지도 않을거야 - https://github.com/Rdatatable/data.table/issues/735 – thelatemail

    3

    :

    reshape2::dcast(DT, Group1 ~ Group2, fun=mean, margins="Group2") 
    
    
        Group1   1   2 (all) 
    1  1 0.6666667 0.0000000 0.4 
    2  2 1.0000000 0.3333333 0.6 
    3  3 0.2500000 0.0000000 0.2 
    4  4 0.0000000 0.0000000 0.0 
    

    @thelatmail이 잘 조절되지 않는이 방법은 아래 코멘트에 주목했다. 결국 margins should be available이 data.table의 dcast에 저장됩니다. 이는 더 효율적입니다.

    못생긴 해결 방법 :

    DT[, c(
        dcast(.SD, Group1 ~ Group2, fun=mean), 
        all = .(dcast(.SD, Group1 ~ ., fun=mean)$.) 
    )] 
    
    
        Group1   1   2 all 
    1:  1 0.6666667 0.0000000 0.4 
    2:  2 1.0000000 0.3333333 0.6 
    3:  3 0.2500000 0.0000000 0.2 
    4:  4 0.0000000 0.0000000 0.0 
    
    +1

    매우 깔끔한 코드이지만, 실제로는 큰 데이터를 질식시키는 것처럼 보입니다. 필자는 10M 레코드에서이를 테스트했으며 필자가 죽이기 전에 거의 모든 16GB RAM을 먹었습니다. – thelatemail

    +0

    잘 부탁드립니다. @thelatemail, thanks. 이 경우 data.table 구현을 기다려야합니다. – Frank

    +1

    예, 실제 데이터 세트는 약 3 백만 행입니다. 따라서 data.table의 'dcast'를 보류하면됩니다. 감사! –