J'ai une liste de chaînes qui contiennent des caractères aléatoires tels que:
list=list()
list[1] = "djud7+dg[a]hs667"
list[2] = "7fd*hac11(5)"
list[3] = "2tu,g7gka5"
Je voudrais savoir quels numéros sont présents au moins une fois (unique()
) dans cette liste. La solution de mon exemple est:
solution: c(7,667,11,5,2)
Si quelqu'un a une méthode qui ne considère pas 11 comme "onze" mais comme "un et un", cela serait également utile. La solution dans cette condition serait:
solution: c(7,6,1,5,2)
(J'ai trouvé cet article sur un sujet connexe: Extraction de nombres à partir de vecteurs de chaînes )
Pour la deuxième réponse, vous pouvez utiliser gsub
pour supprimer tout de la chaîne qui n'est pas un nombre, puis diviser la chaîne comme suit:
unique(as.numeric(unlist(strsplit(gsub("[^0-9]", "", unlist(ll)), ""))))
# [1] 7 6 1 5 2
Pour la première réponse, en utilisant de manière similaire strsplit
,
unique(na.omit(as.numeric(unlist(strsplit(unlist(ll), "[^0-9]+")))))
# [1] 7 667 11 5 2
PS: ne nommez pas votre variable list
(car il y a une fonction intégrée list
). J'ai nommé vos données comme ll
.
Voici encore une autre réponse, celle-ci utilisant gregexpr
pour trouver les nombres, et regmatches
pour les extraire:
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
# extract the numbers:
nums <- stri_extract_all_regex(list, "[0-9]+")
# Make vector and get unique numbers:
nums <- unlist(nums)
nums <- unique(nums)
Et c'est votre première solution
Pour la deuxième solution, j'utiliserais substr
:
nums_first <- sapply(nums, function(x) unique(substr(x,1,1)))
Vous pouvez utiliser ?strsplit
(comme suggéré dans la réponse de @ Arun dans Extraction de nombres à partir de vecteurs (de chaînes) ):
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
Une solution stringr
avec str_match_all
et les opérateurs canalisés. Pour la première solution:
library(stringr)
str_match_all(ll, "[0-9]+") %>% unlist %>% unique %>% as.numeric
Deuxième solution:
str_match_all(ll, "[0-9]") %>% unlist %>% unique %>% as.numeric
(Remarque: j'ai également appelé la liste ll
)
Découvrez la fonction str_extract_numbers()
du package strex
.
pacman::p_load(strex)
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"
str_extract_numbers(charvec)
#> [[1]]
#> [1] 7 667
#>
#> [[2]]
#> [1] 7 11 5
#>
#> [[3]]
#> [1] 2 7 5
unique(unlist(str_extract_numbers(charvec)))
#> [1] 7 667 11 5 2
Créé le 2018-09-03 par le package reprex (v0.2.0).
Utilisez strsplit en utilisant le modèle comme l'inverse des chiffres numériques: 0-9
Pour l'exemple que vous avez fourni, procédez comme suit:
tmp <- sapply(list, function (k) strsplit(k, "[^0-9]"))
Ensuite, prenez simplement une union de tous les "ensembles" dans la liste, comme ceci:
tmp <- Reduce(union, tmp)
Il vous suffit ensuite de supprimer la chaîne vide.