2012-02-10 11 views
28

मेरे पास data.table है जिसमें कॉलम 2 से 20 के साथ रिक्त स्थान के साथ तार (उदाहरण के लिए, "प्रजाति का नाम") है। मैं उन सभी स्तंभों पर एक साथ str_replace() चलाने के लिए चाहता हूं ताकि सभी "प्रजाति का नाम" "प्रजातियां नाम" बन जाए। मुझे क्या करना है या तो कर सकते हैं:मैं डेटाटेबल पर कैसे आवेदन करूं?

data.table(apply(as.data.frame(dt[,2:dim(dt)[2], with=F]), 2, 
           function(x){ str_replace(x," ","_") })) 

या अगर मैं इसे एक data.table वस्तु के रूप में रखने के लिए, तो मैं इस एक स्तंभ एक समय में कर सकते हैं:

dt[,SpeciesName := str_replace(SpeciesName, " ", "_") 

सभी स्तंभों 2 के माध्यम से के लिए मैं यह करने के लिए कैसे करते हैं उपरोक्त में से एक के समान अंत?

उत्तर

30

पूरी तरह से 2015/11/24 पर फिर से लिखा, पिछले संस्करणों में एक त्रुटि ठीक करने के लिए।

आपके पास कुछ विकल्प हैं।

  1. lapply() को एक एम्बेडेड कॉल के साथ लक्ष्य के सभी कॉलम प्रक्रिया, := का उपयोग कर जगह में संशोधित प्रदान करना। यह := पर अपने एलएचएस पर नामित कई कॉलम के साथ एक साथ असाइनमेंट के लिए बहुत आसान समर्थन पर निर्भर करता है।

  2. उपयोग एक for पाश लक्ष्य कॉलम एक समय में एक, set() का उपयोग कर बदले में हर एक के मूल्य को संशोधित करने के माध्यम से चलाने के लिए।

  3. उपयोग एक for पाश से अधिक पुनरावृति के लिए कई "अनुभवहीन" , [.data.table() को, जिनमें से प्रत्येक एक एकल स्तंभ को संशोधित करता है कहता है।

इन विधियों सभी समान रूप से तेजी से के बारे में लग रहे हैं, तो आप किस स्वाद की ज्यादातर बात हो जाएगा का उपयोग करें। (1) अच्छी तरह से कॉम्पैक्ट है और अभिव्यक्तिपूर्ण है। यह वही है जो मैं अक्सर उपयोग करता हूं, हालांकि आपको (2) पढ़ने में आसान मिल सकता है। चूंकि वे एक समय में कॉलम को संसाधित और संशोधित करते हैं, (2) या (3) दुर्लभ स्थिति में एक लाभ प्राप्त करेंगे जिसमें आपका डेटा.table इतना बड़ा है कि आप सीमाओं के खिलाफ चलने के खतरे में हैं आर सत्र की उपलब्ध स्मृति।

library(data.table) 

## Create three identical 1000000-by-20 data.tables 
DT1 <- data.table(1:1e6, 
      as.data.table(replicate(1e6, paste(sample(letters, nr, TRUE), 
              sample(letters, nr, TRUE))))) 
cnames <- c("ID", paste0("X", 1:19)) 
setnames(DT1, cnames) 
DT2 <- copy(DT1); DT3 <- copy(DT1) 

## Method 1 
system.time({ 
DT1[, cnames[-1] := lapply(DT1[,cnames[-1],with=FALSE], 
         function(x) gsub(" ", "_", x))] 
}) 
## user system elapsed 
## 10.90 0.11 11.06 

## Method 2 
system.time({ 
    for(cname in cnames[-1]) { 
     set(DT2, j=cname, value=gsub(" ", "_", DT2[[cname]])) 
    } 
}) 
## user system elapsed 
## 10.65 0.05 10.70 

## Method 3 
system.time({ 
    for(cname in cnames[-1]) { 
     DT3[ , cname := gsub(" ", "_", DT3[[cname]]), with=FALSE] 
    } 
}) 
## user system elapsed 
## 10.33 0.03 10.37 

set() और := के बारे में अधिक जानकारी के लिए, उनकी मदद के पेज, ?set या ?":=" टाइप करके मिल पढ़ें।

+0

यह एक दिलचस्प मामला है। यहां, 20 में से 1 9 कॉलम प्रतिस्थापित किए जा रहे हैं; ': =' का आरएचएस लगभग सभी तालिका है। ': =' का लाभ अधिक होता है, कहें, एक या दो कॉलम 20 में जोड़े जाते हैं, या 20 के एक या दो कॉलम संशोधित होते हैं। उन मामलों में अधिकांश कॉलम जगह पर छोड़ दिए जाते हैं और ': =' पूरी तालिका की प्रतिलिपि बनाने से बहुत तेज है। –

+0

इसके अलावा, 'सेट() 'v1.8.0 (अभी तक सीआरएएन पर नहीं) में एक नया फ़ंक्शन है जो सीधे': = 'कार्यक्षमता प्रदान करता है। 'सेट() 'लूप के भीतर असाइन करते समय' = = 'से अधिक तेज़ हो सकता है (अधिक प्राकृतिक प्रोग्रामिंग के लिए)। मुखपृष्ठ पर नवीनतम समाचारों में एक उदाहरण है। –

+1

@MatthewDowle - आपकी टिप्पणियों के लिए धन्यवाद।उन्होंने मुझे याद दिलाया कि, सप्ताहांत में, मुझे यहां दिए गए उत्तर के बारे में एक अजीब लग रहा था, और मुझे इसे फिर से देखने के लिए प्रेरित किया। जाहिर है, मेरे पास घबराहट महसूस करने का अच्छा कारण था। कृपया मेरे संशोधित उत्तर पर एक नज़र डालें। इसके अलावा ** कृपया मेरी टिप्पणियों में दिए गए किसी भी सुझाव को मेरे उत्तर ** के पाठ पर जोड़ें, जहां आपको लगता है कि वे मदद कर सकते हैं। मैं 'set() 'पर एक नज़र डालेगा, लेकिन अभी तक चर्चा करने के लिए योग्य महसूस नहीं करता हूं। और, एक बार फिर, डेटाटेबल पैकेज के निरंतर विकास में आपके द्वारा किए गए सभी कार्यों के लिए धन्यवाद! –

6

आप ऐसा कर सकते हैं:

library("stringr") 
dt[, -1] <- lapply(dt[, -1], function(x) str_replace(x," ","_")) 
संबंधित मुद्दे