2016-04-13 51 views
3

我的數據集對於在項目中工作的人重複觀察。我需要一個有兩列的數據框,列出每個人和時間點的項目組合。讓我用一個例子解釋:重構/重塑數據框架(r)

這是我的數據:

ID Week Project  
01 1  101 
01 1  102 
01 1  103 
01 2  101 
01 2  102 
02 1  101 
02 1  102 
02 2  101 

人1(ID = 1)1。這意味着,有項目的六種可能的組合,每週工作三個項目(project_i & project_j)在這個星期。

這就是我需要

ID Week Project_i Project_j 
01 1  101  101 
01 1  101  102 
01 1  101  103 
01 1  102  101 
01 1  102  102  
01 1  102  103 
01 1  103  101 
01 1  103  102 
01 1  103  103 
01 2  101  101 
01 2  101  102 
01 2  102  101 
01 2  102  102 
02 1  101  101 
02 1  101  102 
02 1  102  101 
02 1  102  102 
02 2  101  101 

失去,只有每週有一個項目是不是問題的情況下。

我已經嘗試了基本的r和reshape2了一下,但我無法弄清楚這一點。

+0

現在,我還沒有包含在同一行中的同一個項目ID(即 101 101) –

回答

6

這裏有一種方法:

library(data.table) 
setDT(DT) 

DT[, CJ(P1 = Project, P2 = Project)[P1 != P2], by=.(ID, Week)] 

    ID Week P1 P2 
1: 1 1 101 102 
2: 1 1 101 103 
3: 1 1 102 101 
4: 1 1 102 103 
5: 1 1 103 101 
6: 1 1 103 102 
7: 1 2 101 102 
8: 1 2 102 101 
9: 2 1 101 102 
10: 2 1 102 101 

CJ是笛卡爾加入兩個向量的,把所有的組合。

如果你不想同時使用(101,102)和(102,101),請使用P1 > P2而不是P1 != P2。哦,OP已經改變了問題......所以使用P1 <= P2

+0

這似乎是工作,但r爲仍在運行。你認爲這需要很長時間(或者根本沒有可能)爲200萬觀測值嗎? –

+1

@HJ_r可能不是。您需要考慮您嘗試解決的組合問題。你可以鍵入'combos = DT [,。(n = .N *(.N-1L)),by =。(ID,Week)]'來查看問題的大小。 'combos [,sum(n)]'將顯示結果中的總行數,還可以查看'combos [,summary(n)]','combos [,hist(n)]'等 – Frank

+0

謝謝,最終你的解決方案完美無缺。 –

6

以下是使用dplyrtidyr的解決方案。關鍵的步驟是tidyr::complete()結合dplyr::group_by()

library(dplyr) 
library(tidyr) 

d %>% 
    rename(Project_i = Project) %>% 
    mutate(Project_j = Project_i) %>% 
    group_by(ID, Week) %>% 
    complete(Project_i, Project_j) %>% 
    filter(Project_i != Project_j) 
5

下面是使用expand.grid基本選項:

do.call(rbind, lapply(split(df, paste(df$ID, df$Week)), function(x){ 
    x2 <- expand.grid(ID = unique(x$ID), 
         Week = unique(x$Week), 
         Project_i = unique(x$Project), 
         Project_j = unique(x$Project)) 
    # omit if 101 102 is different from 102 101; make `<` if 101 101 not possible 
    x2[x2$Project_i <= x2$Project_j,] 
})) 

#  ID Week Project_i Project_j 
# 1 1.1 1 1  101  101 
# 1 1.4 1 1  101  102 
# 1 1.5 1 1  102  102 
# 1 1.7 1 1  101  103 
# 1 1.8 1 1  102  103 
# 1 1.9 1 1  103  103 
# 1 2.1 1 2  101  101 
# 1 2.3 1 2  101  102 
# 1 2.4 1 2  102  102 
# 2 1.1 2 1  101  101 
# 2 1.3 2 1  101  102 
# 2 1.4 2 1  102  102 
# 2 2 2 2  101  101