【问题标题】:Inserting random letters at random locations within a string在字符串中的随机位置插入随机字母
【发布时间】:2019-09-08 04:18:09
【问题描述】:

我正在尝试制作一个小脚本来演示 DNA 序列如何以一个句子为例进行进化。我想反复替换或插入字母或单词到 R 中的字符串中。我希望这种情况反复发生,以便人们可以观察字符串随时间的变化。最后,我希望字母变化的可能性大于单词变化的可能性。

到目前为止,我已经定义了一个字符串并创建了字母和单词的列表,并从这两个列表中随机抽样。

但是我不知道如何以设定的概率修改文本。例如,如何使文本中的字母有 50% 的机会被我的字母列表中的字母替换,如果发生这种情况,它应该出现在文本中的随机位置?

我还希望这个过程发生 X 次,以便显示文本随时间的变化。非常感谢任何帮助或建议。我目前不完整的代码如下

#First I define the string
text <- c("This sentence is changing")


#Then make a vector of words from the string
word_list <- strsplit(text, " ")
word_list <- unlist(word_list)


#Also make a vector of letters from the string
letters_and_gaps <- substring(text, seq(1, nchar(text), 1), seq(1, nchar(text), 1))
letters_and_gaps <- unlist(letters_and_gaps)

#Now for probability 1 in 2 or it occuring, select a random character from letters_and_gaps:
sample(letters_and_gaps, 1)
#Then choose a random character in text and replace it with this randomly sampled character:

#Now with probability 1 in 10 or it occuring, select a random word from word_list
sample(letters_and_gaps, 1)
#Then choose a random word in text and replace it with this randomly sampled word:

#Then print the updated text:
text 

#Iteratively repeat this process X times

我的目标是最终将其放入一个 Shiny 应用程序中,用户可以在其中选择不同事件发生的概率(字母与单词替换),然后观察它如何影响文本的演变。

【问题讨论】:

  • 如果一个字符被替换,你是否开始用新词代替原来的词?您是否希望单词和字符按照它们在替换前的句子中的频率成比例地替换到句子中,还是从某个固定频率?您真的要排除句子开头没有出现的单词和字母吗?
  • 感谢 cmets。我最终希望有两种选择,具有不同的概率,一种替换单词或字母,另一种添加单词或字母。和谁在一起都很好。是的,我只需要包含句子开头的单词和字母。

标签: r random text substring


【解决方案1】:

这是实施的开始。我们只是将您的逻辑包装在一个函数中,并使用for 循环一次又一次地应用它。在这里,我将输出放在一个表中,然后只显示唯一的行(可能不包括它变回与前一次迭代相同的字符串但可能不重要的时间),以便您可以看到正在发生的变化。请注意,因为我们是从前一句的单词和字符中采样,并且我们包括空格,所以插入空格时可以形成新单词并且分布将趋于变得更加均匀(如果一个字符很常见,它往往是更频繁地替换)

library(tidyverse)

evolve_sentence <- function(sentence, arg2) {
  chars <- str_split(sentence, "") %>% pluck(1)
  if (runif(1) > 0.5) {
    chars[sample(1:length(chars), 1)] <- sample(chars, 1)
  }
  sentence <- str_c(chars, collapse = "")
  words <- str_split(sentence, " ") %>% pluck(1)
  if (runif(1) > 0.9) {
    words[sample(1:length(words), 1)] <- sample(words, 1)
  }
  sentence <- str_c(words, collapse = " ")
  sentence
}

tbl_evolve <- tibble(iteration = 1:500, text = "This sentence is changing")
for (i in 2:500) {
  tbl_evolve$text[i] <- evolve_sentence(tbl_evolve$text[i - 1])
}
tbl_evolve %>%
  distinct(text, .keep_all = TRUE)
#> # A tibble: 204 x 2
#>    iteration text                     
#>        <int> <chr>                    
#>  1         1 This sentence is changing
#>  2         3 hhis sentence is changing
#>  3         4 hhis sentence is chasging
#>  4         6 hhis sestence is chasging
#>  5        10 hhi  sestence is chasging
#>  6        12 hhi  sesnence is chasging
#>  7        14 hhi  sesnesce is chasging
#>  8        15 hhi  se nesce is chasging
#>  9        18 hhi  se nesceiis chasging
#> 10        20 hhi  se nesceiis chasgihg
#> # … with 194 more rows

reprex package (v0.2.1) 于 2019 年 4 月 17 日创建

【讨论】:

  • 谢谢,这是一个很好的开始。您能否解释一下 1:500 和 2:500,我不确定这些数字反映了什么
  • 1:500 就是我想要的行数。 2:500是因为我们不想改变第一句(原文),所以我们从第二行开始
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多