2017-02-09 8 views
7

तो मेरे पास सड़क के पते वाले डेटासेट हैं, वे बहुत अलग रूप से स्वरूपित हैं। उदाहरण के लिए:पहले नंबर पर केवल स्ट्रिंग को कैसे विभाजित करें

d <- c("street1234", "Street 423", "Long Street 12-14", "Road 18A", "Road 12 - 15", "Road 1/2") 

इससे मैं दो कॉलम बनाना चाहता हूं। 1. एक्स: सड़क के पते और के साथ 2. वाई: नंबर + के साथ जो कुछ भी है। इस तरह:

X   Y 
Street  1234 
Street  423 
Long Street 12-14 
Road  18A 
Road  12 - 15 
Road  1/2 

अब तक मैं strsplit की कोशिश की और यहाँ कुछ इसी तरह के सवाल पीछा किया, उदाहरण के लिए है: strsplit(d, split = "(?<=[a-zA-Z])(?=[0-9])", perl = T))। मुझे सही नियमित अभिव्यक्ति नहीं मिल रही है।

किसी भी मदद की अत्यधिक सराहना की जाती है। आपका अग्रिम में ही बहुत धन्यवाद!

उत्तर

7

वहाँ पत्र और अंक के बीच खाली स्थान के हो सकता है, इसलिए lookarounds के बीच \s* (शून्य या अधिक खाली स्थान के प्रतीक) जोड़ें:

> strsplit(d, split = "(?<=[a-zA-Z])\\s*(?=[0-9])", perl = TRUE) 
[[1]] 
[1] "street" "1234" 

[[2]] 
[1] "Street" "423" 

[[3]] 
[1] "Long Street" "12-14"  

[[4]] 
[1] "Road" "18A" 

[[5]] 
[1] "Road" "12 - 15" 

[[6]] 
[1] "Road" "1/2" 

और आपको लगता है कि पर आधारित स्तंभ बनाना चाहते हैं, तो आप का लाभ उठाने सकता है separatetidyr से पैकेज:

> library(tidyr) 
> separate(data.frame(A = d), col = "A" , into = c("X", "Y"), sep = "(?<=[a-zA-Z])\\s*(?=[0-9])") 
      X  Y 
1  street 1234 
2  Street  423 
3 Long Street 12-14 
4  Road  18A 
5  Road 12 - 15 
6  Road  1/2 
+0

'do.call ('rbind', strsplit (डी, split =" (? <= [A-zA-Z]) \\ s * (? = [0-9]) ", perl = सही)) ' – Sathish

+1

@ साथिश: हाँ, लेकिन चलो ओपी के लिए कुछ छोड़ दें। प्रश्न में कोई डेटा फ्रेम पीढ़ी से संबंधित कोड नहीं है, यह सब रेगेक्स के बारे में है। –

+1

सभी मदद के लिए धन्यवाद। अंत में मैंने प्रदान की गई regex के साथ colsplit का उपयोग किया और उसके बाद उन्हें मौजूदा डेटासेट में बाध्य कर दिया। समाधान फार्म सतीश बहुत अधिक सुरुचिपूर्ण है, धन्यवाद। – Jesse

3

एक गैर regex stringr से str_locate का उपयोग कर दृष्टिकोण में पहले अंक का पता लगाने की स्ट्रिंग और फिर उस स्थान के आधार पर विभाजित, यानी

library(stringr) 

ind <- str_locate(d, '[0-9]+')[,1] 
setNames(data.frame(do.call(rbind, Map(function(x, y) 
      trimws(substring(x, seq(1, nchar(x), y-1), seq(y-1, nchar(x), nchar(x)-y+1))), 
                  d, ind)))[,1:2]), c('X', 'Y')) 

#   X  Y 
#1  street 1234 
#2  Street  423 
#3 Long Street 12-14 
#4  Road  18A 
#5  Road 12 - 15 
#6  Road  1/2 

नोट है कि आप एक (हानिरहित) चेतावनी जो "Road 12 - 15" स्ट्रिंग में विभाजित जो [1] "Road" "12 - 15" ""

+1

इस समाधान के लिए भी आपको धन्यवाद – Jesse

3

यह भी काम करेंगे देता है का परिणाम है प्राप्त करते हैं:

do.call(rbind,strsplit(sub('([[:alpha:]]+)\\s*([[:digit:]]+)', '\\1$\\2', d), split='\\$')) 
#  [,1]   [,2]  
#[1,] "street"  "1234" 
#[2,] "Street"  "423"  
#[3,] "Long Street" "12-14" 
#[4,] "Road"  "18A"  
#[5,] "Road"  "12 - 15" 
#[6,] "Road"  "1/2"  
+1

पॉइंटिन के लिए धन्यवाद: [[: अल्फा:]] और [[: अंक:]] समाधान। यह अधिक पढ़ने योग्य – Jesse

2

हम base R

से sub साथ read.csv उपयोग कर सकते हैं
read.csv(text=sub("^([A-Za-z ]+)\\s*([0-9]+.*)", "\\1,\\2", d), 
     header=FALSE, col.names = c("X", "Y"), stringsAsFactors=FALSE) 
#    X  Y 
#1  street 1234 
#2  Street  423 
#3 Long Street 12-14 
#4  Road  18A 
#5  Road 12 - 15 
#6  Road  1/2 
+1

दिलचस्प समाधान बनाता है! – Jesse

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