2014-04-27 2 views
7

Ho una stringa in una variabile che chiamiamo v1. Questa stringa indica i numeri delle immagini e assume la forma di "Pic 27 + 28". Voglio estrarre il primo numero e memorizzarlo in una nuova variabile chiamata item.R estrarre il primo numero dalla stringa

certo codice che ho provato è:

item <- unique(na.omit(as.numeric(unlist(strsplit(unlist(v1),"[^0-9]+"))))) 

Questo ha funzionato bene, fino a quando mi sono imbattuto in un elenco che è andato:

[1,] "Pic 26 + 25" 
[2,] "Pic 27 + 28" 
[3,] "Pic 28 + 27" 
[4,] "Pic 29 + 30" 
[5,] "Pic 30 + 29" 
[6,] "Pic 31 + 32" 

A questo punto ho più numeri di me voglio , in quanto sta anche afferrando altri numeri univoci (il 25).

In realtà ho provato a farlo con gsub, ma non ho ottenuto nulla per funzionare. L'aiuto sarebbe molto apprezzato!

+0

Sarebbe mai esserci più di 100 immagini. Ad esempio, sarebbe mai "Pic 105 + 104"? –

risposta

9

Suppongo che ti piacerebbe estrarre il primo di due numeri in ogni stringa.

è possibile utilizzare la funzione di stri_extract_first_regex dal pacchetto stringi:

library(stringi) 
stri_extract_first_regex(c("Pic 26+25", "Pic 1,2,3", "no pics"), "[0-9]+") 
## [1] "26" "1" NA 
+0

Ha funzionato alla perfezione, grazie! – kneijenhuijs

1

Per seguire il vostro strsplit tentativo:

# split the strings 
l <- strsplit(x = c("Pic 26 + 25", "Pic 27 + 28"), split = " ") 
l 
# [[1]] 
# [1] "Pic" "26" "+" "25" 
# 
# [[2]] 
# [1] "Pic" "27" "+" "28" 

# extract relevant part from each list element and convert to numeric 
as.numeric(lapply(l , `[`, 2)) 
# [1] 26 27 
3

Nelle risposte di seguito usiamo questi dati di test:

# test data 
v1 <- c("Pic 26 + 25", "Pic 27 + 28", "Pic 28 + 27", "Pic 29 + 30", 
"Pic 30 + 29", "Pic 31 + 32") 

1) gsubfn

library(gsubfn) 

strapply(v1, "(\\d+).*", as.numeric, simplify = c) 
## [1] 26 27 28 29 30 31 

2) sub Ciò richiede pacchetti ma non comporta un'espressione leggermente più regolare:

as.numeric(sub("\\D*(\\d+).*", "\\1", v1)) 
## [1] 26 27 28 29 30 31 

3) read.table Questo comporta nessun espressioni regolari o pacchetti:

read.table(text = v1, fill = TRUE)[[2]] 
## [1] 26 27 28 29 30 31 

In questo esempio particolare fill=TRUE potrebbe essere omesso ma potrebbe essere necessario se i componenti di v1 hanno un numero di campi diverso.

1

È possibile farlo molto bene con la funzione first_number() dal pacchetto filesstrings, o per esigenze di carattere più generale, è possibile utilizzare la funzione di nth_number(). Installalo tramite install.packages("filesstrings").

library(filesstrings) 
#> Loading required package: stringr 
strings <- c("Pic 26 + 25", "Pic 27 + 28", "Pic 28 + 27", 
      "Pic 29 + 30", "Pic 30 + 29", "Pic 31 + 32") 
first_number(strings) 
#> [1] 26 27 28 29 30 31 
nth_number(strings, n = 1) 
#> [1] 26 27 28 29 30 31 
1

Con str_extract da stringr:

library(stringr) 

vec = c("Pic 26 + 25", "Pic 27 + 28", "Pic 28 + 27", 
     "Pic 29 + 30", "Pic 30 + 29", "Pic 31 + 32") 

str_extract(v1, "[0-9]+") 
# [1] "26" "27" "28" "29" "30" "31"