2017-09-12 10 views
4

data.table의 CJ() 메소드가 전체 교차 결합을 실행하는 대신 평가 된 조건에 의해 형성된 벡터를 취하는 옵션이 있는지 궁금합니다.R data.table : (동적) Forward Cross-Joins

데이터 여기서

library(data.table) 
df<-data.table(
    ID=c(18L, 18L, 18L, 46L, 74L, 74L, 165L, 165L), 
    cat=c(1300L, 1320L, 1325L, 1300L, 1300L, 1325L, 1300L, 1325L), 
    low=c(24.625, 16.250, 14.500, 43.625, 58.250, 45.375, 90.750, 77.875), 
    high=c(26.625, 17.500, 15.500, 45.625, 60.000, 47.375, 92.750, 79.875) 
) 

df 
    ID cat low high 
1: 18 1300 24.625 26.625 
2: 18 1320 16.250 17.500 
3: 18 1325 14.500 15.500 
4: 46 1300 43.625 45.625 
5: 74 1300 58.250 60.000 
6: 74 1325 45.375 47.375 
7: 165 1300 90.750 92.750 
8: 165 1325 77.875 79.875 

는, I는 4 개 가지 항목 8 개 관측 IDS (18, 46, 74, 165)의 총이있다. 각 항목은 여러 범주 (고양이 1300, 1320, 1325)에 기록되며 두 가지 측정 (낮은 값과 높음 값)이 사용됩니다.

원하는 출력

는 지금 각 항목 (ID)에 대한 교차를 통해 큰 그 범주 모두 높은 값을 각 카테고리 (고양이)의 낮은 값을 조인하는 테이블을 만들려면 어울리다. 내 원하는 출력은 다음과 같습니다.

ID cat cat_large low high 
1: 18 1300  1320 24.625 17.500 
2: 18 1300  1325 24.625 15.500 
3: 18 1320  1325 16.250 15.500 
4: 74 1300  1325 58.250 47.375 
5: 165 1300  1325 90.750 79.875 

여기에서 cat_high를 추가하여 어느 두 카테고리가 낮음/높음으로 결합되어 있는지 나타냅니다.

불행히도, 전체 교차 결합 (df[,CJ(low=low,high=high),by=.(ID)])을 수정하는 올바른 방법을 찾지 못합니다. 어떤 도움이나 힌트에 감사드립니다.

답변

5

한 가지 방법 :

df[, c(
    CJ(cat = cat, lcat = cat, sorted = FALSE), 
    CJ(low = low, high = high, sorted = FALSE) 
), by=ID][lcat > cat] 

    ID cat lcat low high 
1: 18 1300 1320 24.625 17.500 
2: 18 1300 1325 24.625 15.500 
3: 18 1320 1325 16.250 15.500 
4: 74 1300 1325 58.250 47.375 
5: 165 1300 1325 90.750 79.875 
6

내가 비회용으로 .EACHI을 통해이 작업을 수행 할 수 있다고 생각합니다.

df[, c(.SD,.(larger_cat=cat))][ 
    df, on=.(ID==ID, cat > cat), .(larger_cat, low=i.low, high), by=.EACHI, nomatch=0 
] 

# ID cat larger_cat low high 
#1: 18 1300  1320 24.625 17.500 
#2: 18 1300  1325 24.625 15.500 
#3: 18 1320  1325 16.250 15.500 
#4: 74 1300  1325 58.250 47.375 
#5: 165 1300  1325 90.750 79.875 
+0

내가 할 수있을 것 같은 느낌 :..'DF [DF를, =에 (ID == ID, 고양이> 고양이), (larger_cat = X .cat, low = i.low, high) by by = .EACHI, nomatch = 0]'그러나 약간의 알려지지 않은 이유로 이것은'low'와'high' 출력을 깨뜨린다. – thelatemail

+0

당신의 코멘트를 잘 모르겠다. 나는 df [df, on = (ID == ID, cat> cat), 길이 (i.low), by = .EACHI를 비교하여 i. *와 x. * 벡터가 같은 길이가 아니라는 것을 알아 챘다. , nomatch = 0]'df [df, on = (ID == ID, cat> cat), length (high), by = .EACHI, nomatch = 0] 만약 이것이 유일한 문제라면' rep' 또는'first'는 그것을 고칠 것입니다 ..? – Frank

+2

감사합니다. @thelatemail! 이것은 믿을 수 없을 정도로 빠르게 작동하며 대부분 내 용도로 사용하게 될 것입니다. 나는 미래의 독자가 내 질문 제목에 표시된대로 CJ 솔루션을 찾고 있지만 프랭크의 대답 (동일한 목적을 달성하지만 더 오래 걸립니다)에도 불구하고 똑딱 거리고 있습니다. 당신의 일에 감사드립니다! – Daedalus

2

아니 dplyr 솔루션을하지만, 나는 다음과 같은 다른 옵션을 생각 : 당신은 다음의 출력 변수를 가지고있는 테이블을 선택합니다 i. 접두사를 사용할 수 있습니다.

library(dplyr) 
library(tidyr) 

df2 <- df %>% 
    group_by(ID) %>% 
    complete(low, high) %>% 
    mutate(cat_large = cat) %>% 
    group_by(ID, low) %>% 
    mutate(cat = na.omit(cat)) %>% 
    group_by(ID, high) %>% 
    mutate(cat_large = na.omit(cat_large)) %>% 
    filter(low > high) %>% 
    arrange(ID, desc(low), desc(high)) %>% 
    select(ID, cat, cat_large, low, high) 
df2 
# A tibble: 5 x 5 
# Groups: ID, high [4] 
    ID cat cat_large low high 
    <int> <int>  <int> <dbl> <dbl> 
1 18 1300  1320 24.625 17.500 
2 18 1300  1325 24.625 15.500 
3 18 1320  1325 16.250 15.500 
4 74 1300  1325 58.250 47.375 
5 165 1300  1325 90.750 79.875