2016-02-18 4 views
5

मेरे पास एक फ़ंक्शन है जो 1 पंक्ति के डेटा.table (data.frame) के लिए काम करता है, लेकिन नहीं पूर्ण डेटा.table के लिए काम करते हैं। मैं इनपुट डेटा.table के सभी पंक्तियों को ध्यान में रखने के लिए फ़ंक्शन का विस्तार करना चाहता हूं।एक फ़ंक्शन को विस्तारित करता है जो पूर्ण तालिका (एक सबसेट के बजाय) का उपयोग करने के लिए एक तर्क के रूप में डेटा.table लेता है

एक data.table (tryshort3) जहां एक क्षेत्र एक स्ट्रिंग है, एक और data.table (mapping) से दूसरी स्ट्रिंग से प्रतिस्थापित करने की जरूरत है, MRE इस प्रकार है:

तर्क का सार निम्नलिखित है :

#this is the original data.table 
tryshort3 <- structure(list(country = c("AT", "AT", "MT", "DE", "CH", "XK" 
), name = c("ASDF AG", "ASDF GMBH", "ASDF DF", "ASDF KG", "ASDF SA", 
"ASDF DAF"), address = c("ACDSTR. 3", "ACDSTR. 4", "ACDSTR. 5", 
"ACDSTR. 6", "ACDSTR. 7", "ACDSTR. 8")), .Names = c("country", 
"name", "address"), row.names = c(NA, -6L), class = c("data.table", 
"data.frame")) 



#this is the "mapping 
mapping <- structure(list(country = c("AT", "AT", "DE", "DE", "HU"), short.form = c("AG", 
"GMBH", "GMBH", "EV", "EV"), long.form = c("AKTIENGESELLSCHAFT", 
"GESELLSCHAFT MIT BESCHRANKTER HAFTUNG", "GESELLSCHAFT MIT BESCHRANKTER HAFTUNG", 
"EINGETRAGENE VEREIN", "EGYENI VALLALKOZO")), .Names = c("country", 
"short.form", "long.form"), row.names = c(NA, -5L), class = c("data.table", 
"data.frame"), sorted = "country") 


#this is the function that I am using (please not that both data.tables are keyed, but that has currently no say in the output (just avoids throwing an error): 

substituting_short_form <- function(input) { 
    #supply one data.frame of 1 row, the other data.frame is external to the function 
    #get country from input 
    setkey(input,country) 
    setkey(mapping,country) 
    matched_country <- input$country 
    #subset of mapping to only the country from the input 
    matched_map <- mapping[country == matched_country] 
    #get list of short.forms from matched 
    list_of_relevant_short_forms <- matched_map[,short.form] 
    #which one matches will return true if there is any match, THIS IS A NUMBER THAT WILL HAVE TO BE MATCHED TO mapping again to retrieve the correct form 
    #error catching for when there is no short form found, or no country found if there is no long form it does not matter! 
    indextrue <- tryCatch(which(unlist(lapply(list_of_relevant_short_forms, function(y) grepl(y, input$name)))), error = function(e) return(input)) 
    #substitute 
    pattern_to_substitute <- paste0("(\\s|^)", matched_map[indextrue,short.form], "(\\s|$)") 
    pattern_to_replace <- paste0("\\1", matched_map[indextrue,long.form], "\\2") 
    input$name[1] <- gsub(pattern = pattern_to_substitute, replacement = pattern_to_replace,input$name , perl = TRUE) 
    return(input) 
} 

संक्षेप में, जो इस समारोह कर रहा है, tryshort3 एक इनपुट (वर्तमान में केवल tryshort3[1,] के साथ काम कर) ASN, mapping तालिका में पाया मूल्य ले जा रहा है और क्षेत्र "नाम" में बदल देता है तो जैसे:

> tryshort3[1,] 
    country name address 
1:  AT ASDF AG ACDSTR. 3 
> substituting_short_form(tryshort3[1,]) 
    country     name address 
1:  AT ASDF AKTIENGESELLSCHAFT ACDSTR. 3 

क्या मैं चाहते हैं, मैं एक इनपुट के रूप पूर्ण data.table की आपूर्ति, और एक ही उत्पादन (एक ही लंबाई के एक data.table) मिलता है, यहाँ मेरी उम्मीद उत्पादन होता है:

country     name address 
1:  AT ASDF AKTIENGESELLSCHAFT ACDSTR. 3 
2:  AT ASDF GESELLSCHAFT MIT BESCHRANKTER HAFTUNG ACDSTR. 4 
3:  CH ASDF SA ACDSTR. 7 
4:  DE ASDF KG ACDSTR. 6 
5:  MT ASDF DF ACDSTR. 5 
6:  XK ASDF DAF ACDSTR. 8 

समाधान जो मैं चाहता हूं वह apply(tryshort3, 1, function(x) substituting_short_form(x)) फ़ंक्शन के भीतर से कुछ होगा, शायद डेटा डेटा दोनों की अनुक्रमण क्षमताओं का उपयोग कर, या शायद nlme से भीतर से?

उत्तर

4

शायद तुम कई चरणों में की कोशिश कर सकते हैं::

# create the shortform variable in tryshort3 
tryshort3[, short.form := sub(".+\\s([^s]+)$", "\\1", name)] 

# add the info from mapping 
tryshort3long <- merge(tryshort3, mapping, all.x=TRUE, by=c("country", "short.form")) 

# replace the short form by long form in the name and suppress the variables you don't need 
# (thanks to @DavidArenburg for the simplification of the "replace" part!) 
tryshort3long[!is.na(long.form), 
       name := paste(sub(" .*", "", name), long.form) 
       ][, c("long.form", "short.form") := NULL] 

tryshort3long 
    # country          name address 
# 1:  AT     ASDF AKTIENGESELLSCHAFT ACDSTR. 3 
# 2:  AT ASDF GESELLSCHAFT MIT BESCHRANKTER HAFTUNG ACDSTR. 4 
# 3:  CH         ASDF SA ACDSTR. 7 
# 4:  DE         ASDF KG ACDSTR. 6 
# 5:  MT         ASDF DF ACDSTR. 5 
# 6:  XK         ASDF DAF ACDSTR. 8 

एनबी: एक साधारण पाश प्रयास करें खेद मैं सिर्फ अपने उदाहरण data.table के लिए डाल दिया और एक समारोह

+0

धन्यवाद @ डेविड! :-) मुझे लगा कि इफेलसे से बचने का एक तरीका था ;-) – Cath

3

apply के साथ समस्या यह है कि यह एक मैट्रिक्स के लिए अपने तर्क को मजबूर करेगा।

lst <- list() 
for(i in 1:nrow(tryshort3)) lst[[i]] <- substituting_short_form(tryshort3[i,]) 
rbindlist(lst) 
# country          name address 
# 1:  AT     ASDF AKTIENGESELLSCHAFT ACDSTR. 3 
# 2:  AT ASDF GESELLSCHAFT MIT BESCHRANKTER HAFTUNG ACDSTR. 4 
# 3:  MT         ASDF DF ACDSTR. 5 
# 4:  DE         ASDF KG ACDSTR. 6 
# 5:  CH         ASDF SA ACDSTR. 7 
# 6:  XK         ASDF DAF ACDSTR. 8 
+0

के रूप में नहीं यहां चारों ओर कुछ भी नहीं पढ़ा है, लेकिन हो सकता है कि आप 'सेट' देखें, यदि आप पहले से ही 'लूप' चला रहे हैं ... –

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

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