2013-06-09 16 views
29

ich eine Liste von Strings haben, die zufällige Zeichen enthalten wie:Extrahieren eindeutige Zahlen von Zeichenfolge in R

list=list() 
list[1] = "djud7+dg[a]hs667" 
list[2] = "7fd*hac11(5)" 
list[3] = "2tu,g7gka5" 

Ich würde gerne wissen, welche Zahlen vorhanden mindestens einmal sind (unique()) in dieser Liste. Die Lösung meines Beispiel ist:

Lösung: c(7,667,11,5,2)

Wenn jemand eine Methode, die nicht 11 als „elf“ nicht berücksichtigt, sondern als „eins und eins“, wäre es auch nützlich sein. Die Lösung in diesem Zustand wäre:

Lösung: c(7,6,1,5,2)

(ich diesen Beitrag auf einem verwandtes Thema gefunden: Extracting numbers from vectors of strings)

Antwort

54

Für die zweite Antwort, können Sie gsub verwenden, um alles aus dem String zu entfernen das ist keine Zahl, spaltete dann die Zeichenfolge wie folgt:

unique(as.numeric(unlist(strsplit(gsub("[^0-9]", "", unlist(ll)), "")))) 
# [1] 7 6 1 5 2 

Für die erste Antwort, ähnlich mit strsplit,

unique(na.omit(as.numeric(unlist(strsplit(unlist(ll), "[^0-9]+"))))) 
# [1] 7 667 11 5 2 

PS: Benennen Sie nicht Ihre Variable list (da es eine eingebaute Funktion list ist). Ich habe Ihre Daten als ll bezeichnet.

6

könnten Sie verwenden ?strsplit (wie vorgeschlagen in @ Arun Antwort in Extracting numbers from vectors (of strings)):

l <- c("djud7+dg[a]hs667", "7fd*hac11(5)", "2tu,g7gka5") 

## split string at non-digits 
s <- strsplit(l, "[^[:digit:]]") 

## convert strings to numeric ("" become NA) 
solution <- as.numeric(unlist(s)) 

## remove NA and duplicates 
solution <- unique(solution[!is.na(solution)]) 
# [1] 7 667 11 5 2 
1

Verwendung strsplit als Kehrwert der numerischen Ziffern Muster: 0-9

Für das Beispiel von Ihnen bereitgestellten dies tun:

tmp <- sapply(list, function (k) strsplit(k, "[^0-9]")) 

Dann einfach eine Vereinigung aller nehmen `setzt in der Liste, etwa so:

tmp <- Reduce(union, tmp) 

Dann müssen Sie nur die leere Zeichenfolge entfernen.

+0

Drei identische Antworten in einer Minute voneinander! : D – asb

+0

'strsplit' ist vektorisiert. Sie könnten/sollten Schleifen vermeiden, indem Sie die OP-Daten "aufheben". – Arun

+0

Die Verwendung von 'Reduce' mit 'union' (ist im Grunde eine Schleife) wird auch auf großen Listen sehr zeitaufwendig sein ('unique' und' unlist' wären viel schneller). – Arun

15

Hier ist noch eine andere Antwort, dieser gregexpr mit den Zahlen zu finden, und regmatches sie zu extrahieren:

l <- c("djud7+dg[a]hs667", "7fd*hac11(5)", "2tu,g7gka5") 

temp1 <- gregexpr("[0-9]", l) # Individual digits 
temp2 <- gregexpr("[0-9]+", l) # Numbers with any number of digits 

as.numeric(unique(unlist(regmatches(l, temp1)))) 
# [1] 7 6 1 5 2 
as.numeric(unique(unlist(regmatches(l, temp2)))) 
# [1] 7 667 11 5 2 
4

A stringr Lösung mit str_match_all und verrohrt Betreiber.Für die erste Lösung:

library(stringr) 
str_match_all(ll, "[0-9]+") %>% unlist %>% unique %>% as.numeric 

Zweite Lösung:

str_match_all(ll, "[0-9]") %>% unlist %>% unique %>% as.numeric 

:

7

Eine Lösung mit stringi

# extract the numbers: 

nums <- stri_extract_all_regex(list, "[0-9]+") 

# Make vector and get unique numbers: 

nums <- unlist(nums) 
nums <- unique(nums) 

(Anmerkung Ich habe auch die Liste ll genannt) und das ist deine erste Lösung

Screenshot from on-liner in R

Für die zweite Lösung würde ich substr verwenden:

nums_first <- sapply(nums, function(x) unique(substr(x,1,1))) 
+0

Woher kommt 'stri_extract_all_regex()'? –

+0

Das Stringi-Paket, wie es im Titel sagt – altabq

1

Schauen Sie sich die extract_numbers() Funktion aus dem filesstrings Paket. Installieren Sie es über install.packages("filesstrings").

library(filesstrings) 
#> Loading required package: stringr 
list=list() 
list[1] = "djud7+dg[a]hs667" 
list[2] = "7fd*hac11(5)" 
list[3] = "2tu,g7gka5" 
charvec <- unlist(list) 
print(charvec) 
#> [1] "djud7+dg[a]hs667" "7fd*hac11(5)"  "2tu,g7gka5" 
extract_numbers(charvec) 
#> [[1]] 
#> [1] 7 667 
#> 
#> [[2]] 
#> [1] 7 11 5 
#> 
#> [[3]] 
#> [1] 2 7 5 
unique(unlist(ExtractNumbers(charvec))) 
#> [1] 7 667 11 5 2 
Verwandte Themen