在R中反转仅包含字母的字符串模式

7

我正在学习R语言,遇到一个问题,需要将一个字符串中按字母顺序排列的部分进行反转:

String: "abctextdefgtext"    
StringNew: "cbatextgfedtext"

有没有办法识别字母模式来做到这一点?

欢迎来到SO!你目前尝试了什么?请编辑你的问题:http://stackoverflow.com/posts/43394297/edit - jogo
R是一种用于统计的语言,其中字符串大多数/总是静态数据。 - Frank
@nicola,可能是一个长度为2+的“交集”与abcdefghijklmnopqrstuvwxyz。 - Frank
@nicola - 因为abc是唯一按字母顺序排列的部分,而t并不是紧随其后的字母(如果这是一个东西的话-缺乏更好的术语)。 - Rich Scriven
@RichScriven 是的,但你可能在做出一些推断,这可能不是 OP 想要的。首次阅读时,我以为字符串的部分已经给定了。而你则暗示任务是去寻找它们。最终你才是对的,但是描述非常糟糕,因为只提到了字母顺序,而没有顺序部分。 - nicola
显示剩余2条评论
2个回答

4
这里是一种使用base R的方法,基于示例中展示的模式。 我们将字符串拆分为单个字符 ('v1'),使用match找到具有字母位置(letters)的字符的位置,获取索引的差异并检查它是否等于1('i1')。 使用逻辑向量,我们对向量进行子集分组变量,并根据分组变量反转(rev)向量。 最后,paste字符在一起以获得预期输出。
v1 <- strsplit(str1, "")[[1]]
i1 <- cumsum(c(TRUE, diff(match(v1, letters)) != 1L))
paste(ave(v1, i1, FUN = rev), collapse="")
#[1] "cbatextgfedtext"

或者正如评论中的@alexislaz提到的那样。
 v1 = as.integer(charToRaw(str1))
 rawToChar(as.raw(ave(v1, cumsum(c(TRUE, diff(v1) != 1L)), FUN = rev))) 
 #[1] "cbatextgfedtext"

编辑:

1)根据@alexislaz的评论纠正了一个错误

2)根据@alexislaz在评论中提出的另一种方法进行了更新

数据

str1 <- "abctextdefgtext"

1
基于相同的方法,另一种选择可能是 v1 = as.integer(charToRaw(str1)); rawToChar(as.raw(ave(v1, cumsum(c(TRUE, diff(v1) != 1L)), FUN = rev)))。顺便说一下,在上述方法中似乎无法正确识别“defg”序列。 - alexis_laz
@alexis_laz 非常感谢您发现错误并展示了另一种很棒的方法(我学到了很多)。我不知道它没有匹配。 - akrun

2
你可以在R语言的基础上完成这个操作。
vec <- match(unlist(strsplit(s, "")), letters)
x <- c(0, which(diff(vec) != 1), length(vec))
newvec <- unlist(sapply(seq(length(x) - 1),  function(i) rev(vec[(x[i]+1):x[i+1]])))
paste0(letters[newvec], collapse = "")

#[1] "cbatextgfedtext"

s <- "abctextdefgtext"

  1. 首先找到每个字母在字母序列中的位置 ([1] 1 2 3 20 5 24 20 4 5 6 7 20 5 24 20)
  2. 有了这些位置,你要寻找连续的数字,并且找到后将该序列反转 ([1] 3 2 1 20 5 24 20 7 6 5 4 20 5 24 20)
  3. 最后,你就可以得到最后一行的字母。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接