2015-06-23 10 views
10

मेरे पास एक कॉलम data.frame है जहां कुछ रिक्त स्थान कुछ जगहों को सीमित कर सकते हैं।कुछ रिक्त स्थान को टैब पर बदलें - डिलीमीटर

#expected output 
output <- read.table(text=" 
A 2 2 textA1 textA2 Z1 
B 4 1 textX1 textX2 textX3 Z2 
C 3 5 textA1 Z3",sep="\t") 
# V1 V2 V3     V4 V5 
# 1 A 2 2  textA1 textA2 Z1 
# 2 B 4 1 textX1 textX2 textX3 Z2 
# 3 C 3 5    textA1 Z3 

अनिवार्य रूप से, 1st, 2nd, 3, और एक टैब पर पिछले अंतरिक्ष (या किसी अन्य सीमांकक बदलने के लिए अगर यह बनाता है की जरूरत है:

#input data 
dat <- data.frame(x=c("A 2 2 textA1 textA2 Z1", 
         "B 4 1 textX1 textX2 textX3 Z2", 
         "C 3 5 textA1 Z3")) 
#        x 
# 1  A 2 2 textA1 textA2 Z1 
# 2 B 4 1 textX1 textX2 textX3 Z2 
# 3    C 3 5 textA1 Z3 

यह 5 स्तंभ data.frame में बदलने की जरूरत है कोड के लिए आसान)।

regex के साथ खेलना कुछ भी उपयोगी अभी तक न जताए ...

Note1: वास्तविक डेटा में मैं 1st, 2nd, 3rd, ..., 19 वीं और टैब के लिए पिछले रिक्त स्थान को बदलने के लिए।
नोट 2:V4 में कोई पैटर्न नहीं है, पाठ कुछ भी हो सकता है।
नोट 3: अंतिम कॉलम चर लंबाई के साथ एक शब्द पाठ है।

+2

'v1 <- gsub ("^ ([^] +) \\ s + ([^] +) \\ s + ([^] +) \\ s +" [^] +\ \\ s + ",' \\ 1 आज़माएं , \\ 2, \\ 3, ', $ x x); read.table (text = sub (' + (? = [^] + $) ',', ', V1, perl = TRUE), sep = ",") ' – akrun

+0

धन्यवाद @akrun, कृपया अपना जोड़ें एक उत्तर के रूप में टिप्पणी करें। – zx8754

+0

@akrun नोट देखें, आपका समाधान अभी भी काम करेगा, बस '' \\ 1, \\ 2, ... \\\ 19 'तक विस्तार करने की आवश्यकता है ... ' – zx8754

उत्तर

8

v1 <- gsub("^([^ ]+)\\s+([^ ]+)\\s+([^ ]+)\\s+", '\\1,\\2,\\3,', dat$x) 
read.table(text=sub(' +(?=[^ ]+$)', ',', v1, perl=TRUE), sep=",") 
# V1 V2 V3     V4 V5 
#1 A 2 2  textA1 textA2 Z1 
#2 B 4 1 textX1 textX2 textX3 Z2 
#3 C 3 5    textA1 Z3 

या @ Tensibai पद

n <- 3 
fpat <- function(n){ 
    paste0('^((?:\\w+){', n,'})([\\w ]+)\\s+(\\w+)$') 
} 

read.table(text=gsub(fpat(n), "\\1'\\2' \\3", dat$x, perl=TRUE)) 
# V1 V2 V3     V4 V5 
#1 A 2 2  textA1 textA2 Z1 
#2 B 4 1 textX1 textX2 textX3 Z2 
#3 C 3 5    textA1 Z3 

अधिक स्तंभों के लिए से प्रेरित एक विकल्प,

n <- 19 
v1 <- "A 24 34343 212 zea4 2323 12343 111 dsds 134d 153xd 153xe 153de 153dd dd dees eese tees3 zee2 2353 23335 23353 ddfe 3133" 

read.table(text=gsub(fpat(n), "\\1'\\2' \\3", v1, perl=TRUE), sep='') 
# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 
#1 A 24 34343 212 zea4 2323 12343 111 dsds 134d 153xd 153xe 153de 153dd dd 
# V16 V17 V18 V19     V20 V21 
#1 dees eese tees3 zee2 2353 23335 23353 ddfe 3133 
+1

क्षमा करें मैं दो बार ऊपर नहीं जा सकता शानदार है (मुझे फ़ंक्शन के भीतर पैटर्न बनाने का विचार नहीं था, और gsub कॉल read.table की उद्धृत व्याख्या का लाभ लेने के लिए बहुत अच्छा है) मुझे अभी भी – Tensibai

+1

@Tensibai सीखना है केवल संपादन संभव था क्योंकि आपके चालाक कोड का। मैं कुछ समय के बारे में सोच रहा था, लेकिन यह सही नहीं मिला। सहायता का शुक्रिया। – akrun

3

यहाँ का प्रयास करें जाने के लिए है कि काम करेंगे एक मुड़ तरीका हो सकता है जो कुछ भी आपके पास "शब्द" की संख्या (और यह आपके डेटा पर काम करती है);

res <- gsub("\\w{3,}\\K\\t(?=\\w{3,})", " ", gsub(" ", "\t", dat$x), perl=T) 
res 
# [1] "A\t2\t2\ttextA1 textA2\tZ1"  "B\t4\t1\ttextX1 textX2 textX3\tZ2" "C\t3\t5\ttextA1\tZ3" 

read.table(text=res, sep="\t") 
# V1 V2 V3     V4 V5 
#1 A 2 2  textA1 textA2 Z1 
#2 B 4 1 textX1 textX2 textX3 Z2 
#3 C 3 5    textA1 Z3 

संपादित करें: यह अन्य क्षेत्रों में alphanum वर्णों की संख्या की तुलना में अपनी "शब्दों" में alphanum वर्णों की संख्या पर आधारित है जाने के लिए एक पूरी तरह से अलग तरह से, केवल की संख्या के आधार रिक्त स्थान k आप पिछले एक से पहले प्रतिस्थापित करने की आवश्यकता:

k <- 3 # in your example 
res <- sapply(as.character(dat$x), 
       function(x, k){ 
       pos_sp <- gregexpr(" ", x)[[1]] 
       x <- strsplit(x, "")[[1]] 
       if (length(pos_sp) > k+1) pos_sp <- pos_sp[c(1:k, length(pos_sp))] 
       x[pos_sp] <- "\t" 
       x <- paste(x, collapse="") 
       }, k=k) 

read.table(text=res, sep="\t") 
# V1 V2 V3     V4 V5 
# 1 A 2 2  textA1 textA2 Z1 
# 2 B 4 1 textX1 textX2 textX3 Z2 
# 3 C 3 5    textA1 Z3 
6

स्तंभों की एक चर संख्या के साथ:

library(stringr) 
cols <- 3 
m <- str_match(dat$x, paste0("((?:\\w+){" , cols , "})([\\w ]+) (\\w+)")) 
t <- paste0(gsub(" ", "\t", m[,2]), m[,3], "\t", m[,4]) 

> read.table(text=t,sep="\t") 
    V1 V2 V3     V4 V5 
1 A 2 2  textA1 textA2 Z1 
2 B 4 1 textX1 textX2 textX3 Z2 
3 C 3 5    textA1 Z3 

कॉलम की संख्या बदलें ताकि आप यह जान सकें कि आप कितनी पहले चाहें। regex के लिए:

  • ((?:\\w+){3}) कैप्चर 3 repetitions गैर कैप्चरिंग समूह (?:\w+) जो कम से कम एक अक्षरांकीय चरित्र w+ एक अंतरिक्ष
  • ([\\w ]+) (\w+) कब्जा अक्षरांकीय चार या अंतरिक्ष [\w ]+ से मुक्त पाठ का पालन किया जिसके बाद matche की {3} एक अंतरिक्ष और \w+

एक बार यह हो साथ कब्जा अंतिम शब्द से, पेस्ट 3 भागोंद्वारा लौटाए गए 10 टैब द्वारा पहले समूह m[,2] में रिक्त स्थान को बदलने की देखभाल करना।

m[,1] पूरा मिलान है इसलिए यह यहां उपयोग नहीं किया गया है।


पुराना जवाब:

एक बुनियादी एक मिलान क्षेत्रों की एक निश्चित संख्या के आधार पर:

> read.table(text=gsub("(\\w+) (\\w+) (\\w+) ([\\w ]+) (\\w+)$","\\1\t\\2\t\\3\t\\4\t\\5",dat$x,perl=TRUE),sep="\t") 
    V1 V2 V3     V4 V5 
1 A 2 2  textA1 textA2 Z1 
2 B 4 1 textX1 textX2 textX3 Z2 
3 C 3 5    textA1 Z3 

(w + \) के रूप में कई जोड़े इससे पहले कि आप चाहते हैं, और की संख्या में वृद्धि \ 1 (पीछे संदर्भ)

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