2016-08-29 10 views
6

खोजने का कुशल तरीका मेरे पास उनके प्रबंधक की आईडी के साथ लंबे प्रारूप में (प्रति माह एक पंक्ति प्रति कर्मचारी) कर्मचारियों का डेटाबेस है। मैं एक कॉलम जोड़ना चाहता हूं जिसमें उनके प्रबंधक के प्रबंधक की आईडी (या उनके स्किप स्तर प्रबंधक की आईडी) शामिल हो।प्रबंधक के प्रबंधक की आईडी

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) 

और यहाँ एक समारोह मैं ने लिखा है कि रिटर्न अपेक्षित परिणाम है:

यहाँ एक खिलौना डाटासेट है।

# 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]) 
    } 

जब मैं mapply साथ समारोह का उपयोग करें, सब कुछ ठीक है। ध्यान दें कि कर्मचारी 1 ने कंपनी छोड़ दी, और उन्हें कर्मचारी 5 द्वारा प्रतिस्थापित किया गया, जिसे कर्मचारी 10 द्वारा प्रतिस्थापित किया गया था, जिसे कर्मचारी 12 द्वारा प्रतिस्थापित किया गया था, एक नया किराया।

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 

मेरा प्रश्न: वहाँ एक और अधिक कारगर तरीका यह परिणाम प्राप्त करने के क्या है? वर्तमान में 10,000 पंक्तियों पर भी चलाने में काफी समय लगता है, और मेरे डेटासेट में करीब दस लाख हैं।

मैं भी एक अधिक सामान्य प्रश्न शीर्षक (संभवतः इस एसक्यूएल प्रश्न का एक संस्करण: Most efficient way to find something recursively in a table?) पर सुझाव के लिए खुले हूँ

उत्तर

5

आप एक data.table साथ शामिल हो चला सकते हैं। कैसे इसके लिए एक में शामिल होने के x[i, on=, j] है

वाक्य रचना काम करता है

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 

: मुझे यकीन है कि यह कैसे बहुत तेजी से हो जाएगा नहीं कर रहा हूँ। यह i और on का उपयोग x सबसेट करने के लिए करता है और फिर j देता है। यहां मुख्य बिंदु id = mgr_idi में सेट कर रहा है, इसलिए हम प्रबंधक की पंक्तियों में सबसेट कर रहे हैं।

कॉलम असाइन करने के लिए वाक्यविन्यास DT[, col_name := value] है। इस मामले में, मूल्य पिछले अनुच्छेद में समझाए गए शामिल होने से आता है।

+1

मैंने अपना उदाहरण संपादित किया ताकि mgr_id को पूर्णांक के रूप में घोषित किया जा सके। – BLT

+0

@ बीएलटी ठीक है धन्यवाद, मैंने अभी उस कदम को छोड़ दिया है। – Frank

+1

मेरी मशीन पर 'माइक्रोबेंमार्क' का उपयोग करके ऐसा लगता है कि दोनों विधियों (कम से कम इस छोटे डेटासेट पर) के लिए लिया गया समय तुलनीय है। शायद ओपी हमें बता सकता है कि 10000 पंक्तियों की तुलना में वे कैसे तुलना करते हैं? –

संबंधित मुद्दे