在for循环中替换部分字符串时的奇怪行为

时间:2017-11-13 08:15:57

标签: r string dataframe gsub

我正在尝试使用来自数据框的信息替换字符串中的一系列数字。

我的字符串来自我使用readr包导入的文本文件,如下所示:read_file("Human.txt") 我检查了课程,这是个性格。该字符串包含以下信息(我将其命名为treeString):

"(1,2,((((3),884),(((((519,((516,517),(515,(518,(513,514))))),((((((((458,(457,(455,456))),459),(502,(454,(453,(451,452)))))"

我的数据框(labels.csv)最初是因子格式,但我使用以下命令将第二列的格式更改为字符:labels[,2] = as.character(labels[,2])。看起来像这样

     v1     v2
1    1      name1
2    2      name2
3    3      name3

我的目标是用数据框中的相应名称(即V2)替换字符串中的每个数字。这应该导致以下结果:

"(name1,name2,((((name3),884),(((((519,((516,517),(515,(518,(513,514))))),((((((((458,(457,(455,456))),459),(502,(454,(453,(451,452)))))"

以下是我用来完成此任务的代码:

for(i in 1:nrow(labels)){
  gsub(as.character(i), labels[i,2], treeString)
}

奇怪的是,如果我自己运行gsub()命令(使用指定的数字 - 例如.2)它会进行替换,但是,当我在循环中运行它时,它不会替换数字。< / p>

1 个答案:

答案 0 :(得分:2)

正如Kumar Manglam在评论中指出的那样,您忘记将gsub()的结果分配回treeString

您应该注意的其他事项:您在问题中指定正则表达式的方式也会将"(241)"等模式替换为"(name24name1)"。要避免此行为,您应检查要替换的数字是否以逗号或左括号开头以逗号或右括号结束:

# Option1
for(i in 1:nrow(labelnames)){
   reg_pattern <- paste0("(?<=[(,])(", i, ")(?=[),])")
   treeString  <- gsub(reg_pattern, labelnames$v2[i], treeString, perl=T)
}

另一个更好的选择是删除for - 循环并立即执行所有操作:

# Option2
reg_pattern <- paste0("(?<=[(,])([1-", nrow(labelnames), "])(?=[),])")
treeString  <- gsub(reg_pattern, "name\\1", treeString, perl=T)

# Result
treeString
# "(name1,name2,((((name3),884),(((((519,((516,517),(515,(518,(513,514))))),((((((((458,(457,(455,456))),459),(502,(454,(453,(451,452)))))"

数据

 treeString <- "(1,2,((((3),884),(((((519,((516,517),(515,(518,(513,514))))),((((((((458,(457,(455,456))),459),(502,(454,(453,(451,452)))))"
 labelnames <- structure(list(v1 = 1:3, v2 = c("name1", "name2", "name3")), .Names = c("v1", "v2"), class = "data.frame", row.names = c(NA, -3L))