2016-01-28 31 views
5

में कॉलम प्रति पंक्ति का चयन करने के लिए स्ट्रिंग का उपयोग करें मेरे पास अन्य कॉलम नामों से भरा कॉलम है। मैं प्रत्येक कॉलम नामों में मान प्राप्त करना चाहता हूं।dplyr (या आधार आर)

# three columns with values and one "key" column 
library(dplyr) 
data = data.frame(
    x = runif(10), 
    y = runif(10), 
    z = runif(10), 
    key = sample(c('x', 'y', 'z'), 10, replace=TRUE) 
) 

# now get the value named in 'key' 
data = data %>% mutate(value = VALUE_AT_COLUMN(key)) 

मैं यकीन है कि इस सवाल का जवाब मे बदलें की आलसी eval संस्करण के साथ कुछ करने के लिए है, लेकिन मैं नहीं मेरे जीवन के लिए यह पता लगा सकते हैं।

किसी भी मदद की सराहना की जाएगी।

+1

आप भी डेटा की कोशिश कर सकते '[सी (" एक्स "," वाई "," Z ")] [cbind (seq_len (Nrow (डेटा)), मैच (डेटा $ कुंजी, नाम (डेटा))) ] 'प्रत्येक पंक्ति से ग्रुपिंग से बचने के लिए (शायद, कम, लागत "मैट्रिक्स" के मध्यवर्ती रूपांतरण की लागत के साथ)। –

+0

@alexis_laz मैं एक अधिक विस्तार योग्य दृष्टिकोण पसंद करूंगा जिसे प्रत्येक कॉलम को सूचीबद्ध करने की आवश्यकता नहीं है। – sharoz

+1

कि आपका कॉलम आदेश दिया जाता है पर निर्भर करता है, वहाँ कई मायनों programmaticaly जरूरत लोगों को निकालने के लिए होना चाहिए, 'डेटा [1: 3]', 'डेटा [अद्वितीय (डेटा $ कुंजी)]', 'डेटा [% में नाम (डेटा)%" कुंजी "!]' आदि –

उत्तर

5

यहाँ एक बेस आर समाधान है:

data$value = diag(as.matrix(data[,data$key])) 
+1

दिलचस्प, हालांकि मुझे लगता है कि यह स्मृति कुशल नहीं है। –

+2

नहीं! वहाँ एक और अधिक स्मृति कुशल आधार तरीका हो सकता है, लेकिन यदि आप प्रदर्शन के लिए जा रहे हैं तो आप 'data.table' या' dplyr' को देखना चाहिए। यदि आप अधिक पैकेज लोड नहीं करना चाहते हैं और आपका डेटा बड़ा नहीं है, तो यह काम करेगा। –

6

हम data.table आज़मा सकते हैं। पंक्तियों के क्रम से समूहित 'data.frame' को 'data.table' (setDT(data)) में कनवर्ट करें, हम 'कुंजी' द्वारा निर्दिष्ट कॉलम को सब्सक्राइब करने के लिए .SD का उपयोग करते हैं।

library(data.table) 
setDT(data)[, .SD[, key[[1L]], with=FALSE] ,1:nrow(data)] 

या किसी अन्य विकल्प character वर्ग के लिए 'कुंजी' परिवर्तित करने के बाद get है (यह factor के रूप में) पिछले मामले में के रूप में पंक्तियों की अनुक्रम द्वारा समूहीकरण के बाद।

setDT(data)[, get(as.character(key)), 1:nrow(data)] 

यहाँ यह निश्चित रूप से लगता है जैसे वहाँ यह करने के लिए एक आधार के आर समाधान होना चाहिए do

library(dplyr) 
data %>% 
    group_by(rn = row_number()) %>% 
    do(data.frame(., value= .[[.$key]])) 
+0

मैं इस अन्य पुस्तकालयों का उपयोग कर सकते हैं, लेकिन मैं अभी तक एक और डेटा फ्रेम पुस्तकालय – sharoz

+0

आयात करने के लिए @sharoz यह के साथ संभव है की आवश्यकता होगी, से बचने के लिए कोशिश कर रहा हूँ '' do' का उपयोग कर dplyr', – akrun

+2

आप पोस्ट कर सकते हैं कि एक जवाब के रूप? – sharoz

4

साथ एक विकल्प है, लेकिन सबसे अच्छा मैं कर सकता tidyr के साथ था, पहली को बदलने के लिए व्यापक रूप से डेटा, फिर वांछित कुंजी से मेल खाने वाले उन अवलोकनों के लिए फ़िल्टर करें।

data %>% 
    add_rownames("index") %>% 
    gather(var, value, -index, -key) %>% 
    filter(key == var) 

एक आधार आर समाधान है कि लगभग काम करता है:

data[cbind(seq_along(data$key), data$key)] 

दिए गए आंकड़ों के लिए, यह काम करता है करता है, लेकिन क्योंकि यह एक मैट्रिक्स का उपयोग करता है, यह दो गंभीर समस्या है। एक यह है कि कारक का क्रम मायने रखता है, क्योंकि यह सिर्फ उस पर नियंत्रण कर रहा है, और स्तंभ नाम से कॉलम स्तर से कॉलम का चयन कर रहा है। दूसरा यह है कि परिणामी आउटपुट character है, numeric नहीं, क्योंकि मैट्रिक्स में रूपांतरण में टाइप key कॉलम के कारण चुना जाता है। मुख्य समस्या यह है

की मैट्रिक्स व्यवहार करने के लिए कोई data.frame अनुरूप जब से सरणियों का अनुक्रमण '[' एक भी तर्क 'मैं' के रूप में कई कॉलम के साथ एक मैट्रिक्स के रूप में वहाँ के आयाम हैं हो सकता है है कि वहाँ है 'एक्स' ; नतीजा तब एक वेक्टर होता है जिसमें 'i' की प्रत्येक पंक्ति में सूचकांक के सेट से संबंधित तत्व होते हैं।

इन समस्याओं को देखते हुए, मैं शायद tidyr समाधान के साथ, जाना होगा तथ्य यह है कि कॉलम variably चयन का मतलब है कि वे शायद ही नमूदार इकाई के लिए अलग टिप्पणियों का प्रतिनिधित्व कर रहे हैं के बाद से।

5

एक स्मृति के लिए कुशल और तेजी से समाधान, आप अपने मूल डेटा अपडेट हो जाएगा।एक में शामिल होने के रूप में इस प्रदर्शन से तालिका:

data[.(key2 = unique(key)), val := get(key2), on=c(key="key2"), by=.EACHI][] 

data$key में प्रत्येक key2 मिलान पंक्तियों के लिए गणना कर रहे हैं। उन पंक्तियों को कॉलम के मानों के साथ अद्यतन किया गया है जो key2 में निहित हैं। उदाहरण के लिए, key2="x" पंक्तियों 1,2,6,8,10 साथ मेल खाता है। data$x के संबंधित मान data$x[c(1,2,6,8,10)] हैं। by=.EACHI सुनिश्चित करता है अभिव्यक्ति get(key2)key2 के प्रत्येक मान के लिए मार डाला है।

के बाद से यह कार्रवाई केवल अनन्य मानों यह पंक्ति-वार चल रहा है की तुलना में काफी तेजी से किया जाना चाहिए पर किया जाता है। और चूंकि डेटा.table संदर्भ द्वारा अद्यतन किया गया है, यह काफी स्मृति कुशल होना चाहिए (और यह भी गति में योगदान देता है)।