web-dev-qa-db-fra.com

R strsplit avec plusieurs arguments divisés non ordonnés?

Étant donné une chaîne de caractères

test_1<-"abc def,ghi klm"
test_2<-"abc, def ghi klm"

Je souhaite obtenir

"abc"
"def"
"ghi"

Cependant, en utilisant strsplit, il faut connaître l'ordre des valeurs de fractionnement dans la chaîne, car strsplit utilise la première valeur pour effectuer le premier fractionnement, la seconde pour effectuer le second ... et ensuite, le recyclage.

Mais cela ne veut pas:

strsplit(test_1, c(",", " "))
strsplit(test_2, c(" ", ","))

strsplit(test_2, split=c("[:punct:]","[:space:]"))[[1]]

Je cherche à scinder la chaîne partout où je trouve l'une de mes valeurs de scission en une seule étape.

40

En fait, strsplit utilise également des modèles grep. (Une virgule est un métacaractère regex alors qu'un espace ne l'est pas; d'où la nécessité de doubler les virgules dans l'argument de motif. Ainsi, l'utilisation de "\\s" serait davantage pour améliorer la lisibilité que par nécessité):

> strsplit(test_1, "\\, |\\,| ")
[[1]]
[1] "abc" "def" "ghi" "klm"

> strsplit(test_2, "\\, |\\,| ")
[[1]]
[1] "abc" "def" "ghi" "klm"

Sans utiliser à la fois \\, et \\, (notez l'espace supplémentaire que SO ne s'affiche pas), vous auriez obtenu des valeurs de caractère (0). J'aurais peut-être été plus clair si j'avais écrit:

> strsplit(test_2, "\\,\\s|\\,|\\s")
[[1]]
[1] "abc" "def" "ghi" "klm"

@Fojtasek a tout à fait raison: l'utilisation de classes de caractères simplifie souvent la tâche car elle crée un OU logique implicite:

> strsplit(test_2, "[, ]+")
[[1]]
[1] "abc" "def" "ghi" "klm"

> strsplit(test_1, "[, ]+")
[[1]]
[1] "abc" "def" "ghi" "klm"
50
42-

Si vous n'aimez pas les expressions régulières, vous pouvez appeler strsplit() plusieurs fois:

strsplits <- function(x, splits, ...)
{
    for (split in splits)
    {
        x <- unlist(strsplit(x, split, ...))
    }
    return(x[!x == ""]) # Remove empty values
}

strsplits(test_1, c(" ", ","))
# "abc" "def" "ghi" "klm"
strsplits(test_2, c(" ", ","))
# "abc" "def" "ghi" "klm"

Mise à jour pour l'exemple ajouté

strsplits(test_1, c("[[:punct:]]","[[:space:]]"))
# "abc" "def" "ghi" "klm"
strsplits(test_2, c("[[:punct:]]","[[:space:]]"))
# "abc" "def" "ghi" "klm"

Mais si vous utilisez des expressions rationnelles, vous pouvez également utiliser l'approche de @DWin:

strsplit(test_1, "[[:punct:][:space:]]+")[[1]]
# "abc" "def" "ghi" "klm"
strsplit(test_2, "[[:punct:][:space:]]+")[[1]]
# "abc" "def" "ghi" "klm"
6
jthetzel

Vous pourriez aller avec strsplit(test_1, "\\W").

5
danas.zuokas
 test_1<-"abc def,ghi klm"
 test_2<-"abc, def ghi klm"
 key_words <- c("abc","def","ghi")
 matches <- str_c(key_words, collapse ="|")
 str_extract_all(test_1, matches)
 str_extract_all(test_2, matches)
1
zhan2383