【问题标题】:R: combinatorial string replacementR:组合字符串替换
【发布时间】:2014-06-23 12:01:22
【问题描述】:

我正在寻找一个基于 gsub 的函数,它可以让我进行组合字符串替换,这样如果我有任意数量的字符串替换规则

replrules=list("<x>"=c(3,5),"<ALK>"=c("hept","oct","non"),"<END>"=c("ane","ene"))

和一个目标字符串

string="<x>-methyl<ALK><END>"

它会给我一个数据框,其中包含最终的字符串名称和在

中所做的替换
name                x        ALK     END
3-methylheptane     3        hept    ane
5-methylheptane     5        hept    ane
3-methyloctane      3        oct     ane
5-methyloctane      5        ...     ...
3-methylnonane      3
5-methylnonane      5
3-methylheptene     3
5-methylheptene     5
3-methyloctene      3
5-methyloctene      5
3-methylnonene      3
5-methylnonene      5

目标字符串可以是任意结构,例如也可以是string="1-&lt;ALK&gt;anol",或者每个模式都可能出现多次,如string="&lt;ALK&gt;anedioic acid, di&lt;ALK&gt;yl ester"

在 R 中做这种事情最优雅的方式是什么?

【问题讨论】:

  • 你怎么知道 x = 3 在第一行表示“hept”和“ane”?它们都井井有条吗?
  • 顺序对我来说无关紧要 - 但我假设在这种情况下,首先循环遍历 中的 val,然后遍历 中的 val,然后遍历

标签: string r gsub


【解决方案1】:

怎么样

d <- do.call(expand.grid, replrules)

d$name <- paste0(d$'<x>', "-", "methyl", d$'<ALK>', d$'<END>')


编辑

这似乎可行(将这些替换为strplit

string = "<x>-methyl<ALK><END>"
string2 = "<x>-ethyl<ALK>acosane"
string3 = "1-<ALK>anol"

使用理查兹正则表达式

d <- do.call(expand.grid, list(replrules, stringsAsFactors=FALSE))
names(d) <- gsub("<|>","",names(d))

s <- strsplit(string3, "(<|>)", perl = TRUE)[[1]]

out <- list()

for(i in s) {
  out[[i]] <- ifelse (i %in% names(d), d[i], i)
}

d$name <- do.call(paste0,  unlist(out, recursive=F))


编辑

这应该适用于重复项目

d <- do.call(expand.grid, list(replrules, stringsAsFactors=FALSE))
names(d) <- gsub("<|>","",names(d))

string4 = "<x>-methyl<ALK><END>oate<ALK>"

s <- strsplit(string4, "(<|>)", perl = TRUE)[[1]]
out <- list()
for(i in seq_along(s)) {
  out[[i]] <- ifelse (s[i] %in% names(d), d[s[i]], s[i])
}
d$name <- do.call(paste0,  unlist(out, recursive=F))

【讨论】:

  • 哈太完美了——只有两行——恭喜你,谢谢你的帮助!!
  • 对不起,也许太早接受了这个答案 - 理想情况下,我希望目标字符串具有任意结构,例如它也可能是 string="-ethylacosane",然后技巧是在这种情况下将 -ethyl 和 acosane 插入数据框 d 的右列中。有什么想法吗?
  • 非常感谢 - 这似乎不适用于每种模式多次出现的情况,例如string="-methyloate" as then line s )", perl = TRUE)[[1] ] 然后给出 "" "-methyl" "" "" "oate" (这里的最后一个元素应该被拆分)。有什么想法吗?
  • 哈非常感谢所有的努力 - 最后一个解决方案完美!太感谢了!绝对应该阅读那些正则表达式...
【解决方案2】:

好吧,我不确定我们甚至可以为您的问题提供“正确”的答案,但希望这有助于给您一些想法。

好的,所以在s 中,我只是将字符串拆分到可能最重要的位置。然后g 获取r 的每个元素中的第一个值。然后我构建了一个数据框作为例子。那么dat 是它的外观的单行示例。

> (s <- strsplit(string, "(?<=l|\\>)", perl = TRUE)[[1]])
# [1] "<x>"     "-methyl" "<ALK>"   "<END>"  
> g <- sapply(replrules, "[", 1)
> dat <- data.frame(name = paste(append(g, s[2], after = 1), collapse = ""))
> dat[2:4] <- g
> names(dat)[2:4] <- sapply(strsplit(names(g), "<|>"), "[", -1)
> dat
#              name x  ALK END
# 1 3-methylheptane 3 hept ane

【讨论】:

  • 非常感谢 - 我将在此基础上进一步思考。我看到的问题是它只适用于我的第一个例子,但不适用于甲基不必插入第二列的一般情况,例如当 之间不包含超过 2 个字符串部分时
  • 嗯,是的,它很笼统,因为我没有适当的数据。有了适当的数据,我就会知道要索引的内容和位置。但是我们肯定可以从中构造一个有用的函数。
  • 偷了你的正则表达式 - 希望没问题 :)
  • 不用担心。我也是从之前的帖子中借来的。
猜你喜欢
  • 2013-01-28
  • 1970-01-01
  • 2014-09-28
  • 2016-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 2012-04-26
相关资源
最近更新 更多