Comment inverser une chaîne dans R

J'essaie de m'enseigner R et en faisant quelques exemples de problèmes, je suis tombé sur la nécessité d'inverser une chaîne.

Voici ce que j'ai essayé jusqu'à présent mais l'opération de pâte ne semble pas avoir d'effet.

Il doit y avoir quelque chose que je ne comprends pas sur les listes? (Je ne comprends pas non plus pourquoi j'ai besoin du [[1]] après strsplit.)

> test <- strsplit("greg", NULL)[[1]]
> test
[1] "g" "r" "e" "g"
> test_rev <- rev(test)
> test_rev
[1] "g" "e" "r" "g"
> paste(test_rev)
[1] "g" "e" "r" "g"
40
r
demandé sur mpalanco 2012-11-28 23:33:18

14 réponses

Comme le souligne @mplourde, vous voulez l'argument collapse:

paste(test_rev, collapse='')

La plupart des commandes de R sont vectorisées, mais la façon dont la commande gère exactement les vecteurs dépend de la commande. {[3] } fonctionnera sur plusieurs vecteurs, combinant le i ème élément de chacun:

> paste(letters[1:5],letters[1:5])
[1] "a a" "b b" "c c" "d d" "e e"

collapse lui dit d'opérer dans un vecteur à la place.

18
répondu Ari B. Friedman 2012-11-28 19:43:08

À partir de ?strsplit, une fonction qui va inverser chaque chaîne dans un vecteur de chaînes:

## a useful function: rev() for strings
strReverse <- function(x)
        sapply(lapply(strsplit(x, NULL), rev), paste, collapse="")
strReverse(c("abc", "Statistics"))
# [1] "cba"        "scitsitatS"
46
répondu Josh O'Brien 2012-11-28 20:05:54

stringi a eu cette fonction depuis assez longtemps:

stringi::stri_reverse("abcdef")
## [1] "fedcba"

Notez Également qu'il est vectorisé:

stringi::stri_reverse(c("a", "ab", "abc"))
## [1] "a"   "ba"  "cba"
26
répondu gagolews 2016-06-14 14:09:45

Vous pouvez également utiliser le paquet IRanges.

library(IRanges)
x <- "ATGCSDS"
reverse(x)
# [1] "SDSCGTA"

Vous pouvez également utiliser le paquet Biostrings.

library(Biostrings)
x <- "ATGCSDS"
reverse(x)
# [1] "SDSCGTA"
9
répondu Ven Yao 2015-11-12 15:04:38

Ce qui suit peut être un moyen utile d'inverser un vecteur de chaînes x, et est légèrement plus rapide (et plus efficace en mémoire) car il évite de générer une liste (comme dans l'utilisation strsplit):

x <- rep( paste( collapse="", LETTERS ), 100 )
str_rev <- function(x) {
  sapply( x, function(xx) { 
    intToUtf8( rev( utf8ToInt( xx ) ) )
  } )
}
str_rev(x)

Si vous savez que vous allez travailler avec des caractères ASCII et des questions de vitesse, il existe une implémentation C rapide pour inverser un vecteur de chaînes intégré à Kmisc:

install.packages("Kmisc")
str_rev(x)
8
répondu Kevin Ushey 2013-08-07 05:19:02

Si vos données sont dans un data.frame, vous pouvez utiliser sqldf:

myStrings <- data.frame(forward = c("does", "this", "actually", "work"))
library(sqldf)
sqldf("select forward, reverse(forward) `reverse` from myStrings")
#    forward  reverse
# 1     does     seod
# 2     this     siht
# 3 actually yllautca
# 4     work     krow
6
répondu A5C1D2H2I1M1N2O1R2T1 2012-11-29 08:38:39

Voici une fonction qui retourne toute la chaîne inversée, ou éventuellement la chaîne inverse en ne gardant que les éléments spécifiés par index, en comptant en arrière à partir du dernier caractère.

revString = function(string, index = 1:nchar(string)){
  paste(rev(unlist(strsplit(string, NULL)))[index], collapse = "")
}

Tout d'abord, définissez une chaîne facilement reconnaissable comme exemple:

(myString <- paste(letters, collapse = ""))

[1] "abcdefghijklmnopqrstuvwxyz"

Maintenant essayer la fonction revString, avec et sans index:

revString(myString)

[1] "zyxwvutsrqponmlkjihgfedcba"

revString(myString, 1:5)

[1] "zyxwv"

2
répondu Paul McMurdie 2015-07-06 18:00:15

Le Code suivant prendra l'entrée de l'utilisateur et inversera la chaîne entière -

revstring=function(s)
print(paste(rev(strsplit(s,"")[[1]]),collapse=""))

str=readline("Enter the string:")
revstring(str)
2
répondu shivamt042 2017-10-16 15:34:06

Voici une solution avec gsub. Bien que je convienne que c'est plus facile avec strsplit et paste (comme indiqué dans les autres réponses), il peut être intéressant de voir que cela fonctionne aussi avec des expressions régulières:

test <- "greg"

n <- nchar(test) # the number of characters in the string

gsub(paste(rep("(.)", n), collapse = ""),
     paste("", seq(n, 1), sep = "\\", collapse = ""),
     test)

# [1] "gerg"
1
répondu Sven Hohenstein 2012-11-29 07:26:49
##function to reverse the given word or sentence

reverse <- function(mystring){ 
n <- nchar(mystring)
revstring <- rep(NA, n)
b <- n:1
c <- rev(b)
for (i in 1:n) {
revstring[i] <- substr(mystring,c[(n+1)- i], b[i])
 }
newrevstring <- paste(revstring, sep = "", collapse = "")
return (cat("your string =", mystring, "\n",
("reverse letters = "), revstring, "\n", 
"reverse string =", newrevstring,"\n"))
}
1
répondu sumalatha 2015-05-06 04:41:19

Le moyen le plus simple d'inverser la chaîne:

#reverse string----------------------------------------------------------------
revString <- function(text){
  paste(rev(unlist(strsplit(text,NULL))),collapse="")
}

#example:
revString("abcdef")
1
répondu Uekonometria Uekonometria 2017-02-17 09:54:11

Voici une autre solution de base-R:

# Define function
strrev <- function(x) {
  nc <- nchar(x)
  paste(substring(x, nc:1, nc:1), collapse = "")
}

# Example
strrev("Sore was I ere I saw Eros")
[1] "sorE was I ere I saw eroS"

Solution a été inspiré par ces diapositives U. Auckland .

1
répondu snoram 2017-07-18 16:10:42

Vous pouvez faire avec la fonction rev() comme mentionné dans un post précédent.

`X <- "MyString"

RevX <- paste(rev(unlist(strsplit(X,NULL))),collapse="")

Sortie: "gnirtSyM"

Merci,

1
répondu Ankit Deshmukh 2018-03-26 09:05:35

Donc, apparemment, les développeurs JS frontaux sont invités à le faire (pour des interviews) dans JS sans utiliser les fonctions inverses intégrées. Cela m'a pris quelques minutes, mais je suis venu avec:

string <- 'hello'

foo <- vector()

for (i in nchar(string):1) foo <- append(foo,unlist(strsplit(string,''))[i])
paste0(foo,collapse='')

Qui pourraient tous être enveloppés dans une fonction...

Qu'en est-il des fonctions d'ordre supérieur? Réduire?

0
répondu bboppins 2018-02-18 01:53:09