2016-08-29 18 views
6

Yöneticilerimin kimliği ile uzun bir formda (çalışan başına ayda bir satır) bir çalışan veritabanına sahibim. Yöneticisinin yöneticisinin kimliğini (veya atlama düzeyindeki yöneticilerinin kimliğini) içeren bir sütun eklemek istiyorum. BuradaYöneticinin yönetici kimliğini bulmak için etkili bir yol

id <- c(seq.int(1,11), seq.int(2,12)) 
mgr_id <- as.integer(c(NA, 1, 1, 2, 2, 2, 2, 3, 3, 5, 5, #period 1 
         NA, 2, 5, 2, 5, 5, 3, 3, 5, 10, 10)) #period 2 
period <- c(rep(1, 11), rep(2, 11)) 
left_company <- c(1, rep(0, 21)) 
joined_company <- c(rep(0, 21), 1) 

df <- data.frame(id, mgr_id, period, left_company, joined_company) 

Ve beklenen sonuçları verir yazdığım bir fonksiyonudur: Burada

bir oyuncak veri kümesi olduğunu. Ben mapply ile işlevini kullandığınızda

# finds the employee's manager in the correct period, and returns that manager's id 

    get_mgr_mgr_id <- function(manager_id, period){ 
     mgr_mgr_id <- df$mgr_id[df$id == manager_id & df$period == period] 
     return(mgr_mgr_id[1]) 
    } 

, her şey yolunda. Çalışan 1'in şirketten ayrıldığını ve yerine çalışan 10 ile yer değiştirdiğini, çalışanın yerine 10, yerine çalışanın 12, yeni bir işe alındığını belirtti.

df$mgr_mgr_id <- mapply(get_mgr_mgr_id, df$mgr_id, df$period) 

df 
    id mgr_id period left joined mgr_mgr_id 
1 1  NA  1 1  0   NA 
2 2  1  1 0  0   NA 
3 3  1  1 0  0   NA 
4 4  2  1 0  0   1 
5 5  2  1 0  0   1 
6 6  2  1 0  0   1 
7 7  2  1 0  0   1 
8 8  3  1 0  0   1 
9 9  3  1 0  0   1 
10 10  5  1 0  0   2 
11 11  5  1 0  0   2 
12 2  NA  2 0  0   NA 
13 3  2  2 0  0   NA 
14 4  5  2 0  0   2 
15 5  2  2 0  0   NA 
16 6  5  2 0  0   2 
17 7  5  2 0  0   2 
18 8  3  2 0  0   2 
19 9  3  2 0  0   2 
20 10  5  2 0  0   2 
21 11  10  2 0  0   5 
22 12  10  2 0  1   5 

Sorum: bu sonucu elde etmek için daha verimli bir yol var mı? Şu anda 10.000 satırda bile çalışmak oldukça uzun zaman alıyor ve veri kümem milyona yaklaşıyor. Bir data.table ile katılmak çalıştırabilirsiniz

cevap

5

:

Ben de (Most efficient way to find something recursively in a table? bu SQL soru muhtemelen bir versiyonu) daha genel bir soru başlığına önerilere açığım. Ben öyle olacak ne kadar daha hızlı emin değilim:

library(data.table) 
setDT(df) 

df[, m2id := df[.(id = mgr_id, period = period), on=c("id", "period"), mgr_id]] 

    id mgr_id period left_company joined_company m2id 
1: 1  NA  1   1    0 NA 
2: 2  1  1   0    0 NA 
3: 3  1  1   0    0 NA 
4: 4  2  1   0    0 1 
5: 5  2  1   0    0 1 
6: 6  2  1   0    0 1 
7: 7  2  1   0    0 1 
8: 8  3  1   0    0 1 
9: 9  3  1   0    0 1 
10: 10  5  1   0    0 2 
11: 11  5  1   0    0 2 
12: 2  NA  2   0    0 NA 
13: 3  2  2   0    0 NA 
14: 4  5  2   0    0 2 
15: 5  2  2   0    0 NA 
16: 6  5  2   0    0 2 
17: 7  5  2   0    0 2 
18: 8  3  2   0    0 2 
19: 9  3  2   0    0 2 
20: 10  5  2   0    0 2 
21: 11  10  2   0    0 5 
22: 12  10  2   0    1 5 
    id mgr_id period left_company joined_company m2id 

o katılmak bir x[i, on=, j] olduğu için

sözdizimi nasıl çalışır. x alt kümesini i ve on kullanır ve j döndürür. Buradaki önemli nokta, i numaralı telefondan id = mgr_id ayarını yapmaktır. Bu nedenle, yöneticinin satırlarına ayırıyoruz.

Bir sütun atama sözdizimi DT[, col_name := value]'dur. Bu durumda, değer son paragrafta açıklanan birleştirmeden gelir.

+1

Örneğimi düzenledim, böylece mgr_id bir tamsayı olarak bildirilsin. – BLT

+0

@BLT Teşekkürler, şimdi bu adımı düşürdüm. – Frank

+1

'microbenchmark' kullanarak, makinemde her iki yöntem için de (en azından bu küçük veri kümesinde) zamanın karşılaştırılabilir olduğu anlaşılıyor. Belki OP, 10000 satırı nasıl karşılaştırdıklarını bize bildirebilir mi? –

İlgili konular