2015-12-23 14 views
7

Spero di poterlo spiegare così è facile per te. Avrei bisogno di questo in quanto le informazioni mancanti in una stringa sono contrassegnate da tre spazi e, sorprendentemente, non eseguono uno \n per la prossima informazione.R - Dividi da " n" o tre spazi e conserva almeno uno spazio quando ci sono tre spazi

Immaginate ho una stringa del tipo:

string <- "abc 
    def 
ghi jkl" 

voglio l'uscita di un espressione regolare (magari con strsplit() con una funzione più avanzata) di essere:

[[1]] 
[1] "abc" "" "def" "ghi" "" "jkl" 

che si divide quando si trova uno \n e che divide e inserisce uno spazio bianco quando trova tre spazi. Devo contrassegnare le informazioni mancanti come un altro valore. In caso contrario, ciò interrompe il mio script, pensando che le informazioni successive siano, ad esempio, tre spazi concatenati con la stringa def.

Grazie

risposta

5

Qui ci sono due soluzioni che utilizzano entrambi strsplit ma differiscono nel modo in cui si sono divisi:

1) per parti separate del ritorno a capo Rimuovi tutti i ritorni a capo dando s1 e quindi aggiungere un ritorno a capo dopo ogni terzo personaggio dando s2. Dividi s2 su newline e sostituisci ogni occorrenza di tre spazi consecutivi con la stringa vuota.

Split <- function(string) { 
    s1 <- gsub("\n", "", string) 
    s2 <- gsub("(.{3})", "\\1\n", s1) 
    spl <- strsplit(s2, "\n") 
    lapply(spl, function(s) replace(s, s == " ", "")) 
} 

# test 
string <- "abc\n def\nghi jkl" 
Split(string) 
## [[1]] 
## [1] "abc" "" "def" "ghi" "" "jkl" 

2) diviso sullo zero larghezza regexp 3 char Rimuovere le nuove righe e diviso utilizzando l'espressione regolare indicata. Alla fine sostituisci ogni tre spazi consecutivi con la stringa vuota.

Split2 <- function(string) { 
    s1 <- gsub("\n", "", string) 
    spl <- strsplit(s1, "(?<=...)", perl = TRUE) 
    lapply(spl, function(s) replace(s, s == " ", "")) 
} 

# test 
string <- "abc\n def\nghi jkl" 
Split2(string) 
## [[1]] 
## [1] "abc" "" "def" "ghi" "" "jkl" 

Nota: 1. Notare che le altre risposte fornite a questa domanda non funzionano per la stringa di input (che ha due campi vuoti in successione) ma le risposte qui non correttamente riconoscere due vuote 3 campi di caratteri in successione dopo il abc campo:

string2 <- "abc\n  def\nghi jkl" # 6 spaces before d, 3 spaces before j 

Split(string2) 
## [[1]] 
## [1] "abc" "" "" "def" "ghi" "" "jkl" 

Split2(string2) 
## [[1]] 
## [1] "abc" "" "" "def" "ghi" "" "jkl" 

Nota 2: Le due soluzioni sopra possono anche essere ben espressa utilizzando un oleodotto magrittr:

library(magrittr) 
string %>% 
    gsub(pattern = "\n", replacement = "") %>% 
    gsub(pattern = "(.{3})", replacement = "\\1\n") %>% 
    strsplit("\n") %>% 
    lapply(function(s) replace(s, s == " ", "")) 

## [[1]] 
## [1] "abc" "" "def" "ghi" "" "jkl" 


library(magrittr) 
string %>% 
    gsub(pattern = "\n", replacement = "") %>% 
    strsplit("(?<=...)", perl = TRUE) %>% 
    lapply(function(s) replace(s, s == " ", "")) 

## [[1]] 
## [1] "abc" "" "def" "ghi" "" "jkl" 
3
(string <- "abc 
    def 
ghi jkl") 
# [1] "abc\n def\nghi jkl" 

rle(strsplit(string, '\\s')[[1]])$values 
# [1] "abc" "" "def" "ghi" "" "jkl"