为了更改结果数据框中的值,我使用基于stringr
的函数,在Hadley Wickham(https://stackoverflow.com/a/12829731/2872891)的答案中推荐。除了最后将df
更改为return (df)
之外,我保留了函数的完整性,我更喜欢这个。但是,我看到一些奇怪的行为,我不确定是什么原因。 replace_all
的后续调用,特别是调用#3和#4,无法恢复原始数据:http:
和mailto:
。随后是可重现的示例。
数据(只有一条数据记录):
请在GitHub上看到这个要点:https://gist.github.com/abnova/1709b1e0cf8a57570bd1#file-gistfile1-r
代码(为简洁起见,我通过详细解释删除了我的评论):
DATA_SEP <- ":"
rx <- "([[:alpha:]][^.:]|[[:blank:]])::([[:alpha:]][^:]|[[:blank:]])"
results <- gsub(rx, "\\1@@\\2", results)
results <- gsub(": ", "!@#", results) # should be after the ::-gsub
results <- gsub("http://", "http//", results)
results <- gsub("mailto:", "mailto@", results)
results <- gsub("-\\r\\n", "-", results) # order is important here
results <- gsub("\\r\\n", " ", results)
results <- gsub("\\n:gpl:962356288", ":gpl:962356288", results)
results <- readLines(textConnection(unlist(results)))
numLines <- length(results)
results <- lapply(results, function(x) gsub(".$", "", x))
data <- read.table(textConnection(unlist(results)),
header = FALSE, fill = TRUE,
sep = DATA_SEP, quote = "",
colClasses = "character", row.names = NULL,
nrows = numLines, comment.char = "",
strip.white = TRUE)
replace_all(data, fixed("!@#"), ": ")
replace_all(data, fixed("@@"), "::")
replace_all(data, fixed("http//"), "http://")
replace_all(data, fixed("mailto@"), "mailto:")
结果 - 实际:
> data$V3
[1] "http//www.accessgrid.org/"
> data$V17
[1] "http//mailto@accessgrid-tech@lists.sourceforge.net"
结果 - 预期:
> data$V3
[1] "http://www.accessgrid.org/"
> data$V17
[1] "http://mailto:accessgrid-tech@lists.sourceforge.net"
我感谢任何帮助和/或建议。
答案 0 :(得分:2)
我对此进行了测试,发现使用多次调用replace_all
进行替换时出现问题。
replace_all(data, fixed("!@#"), ": ")
replace_all(data, fixed("@@"), "::")
replace_all(data, fixed("http//"), "http://")
replace_all(data, fixed("mailto@"), "mailto:")
您没有看到预期输出的原因是因为您之后没有将replace_all
调用的结果分配给任何内容。它应该是......
data <- replace_all(data, fixed("!@#"), ": ")
data <- replace_all(data, fixed("@@"), "::")
data <- replace_all(data, fixed("http//"), "http://")
data <- replace_all(data, fixed("mailto@"), "mailto:")
data
在不使用stringr
的情况下执行此操作的另一种方法是创建包含模式和替换的向量,并通过一次调用来遍历它们。
re <- c('!@#', '@@', 'http//', 'mailto@')
val <- c(': ', '::', 'http://', 'mailto:')
replace_all <- function(pattern, repl, x) {
for (i in 1:length(pattern))
x <- gsub(pattern[i], repl[i], x, fixed=T)
x
}
replace_all(re, val, data)
输出
[3] "http://www.accessgrid.org/"
[17] "http://mailto:accessgrid-tech@lists.sourceforge.net"
答案 1 :(得分:0)
在几乎完成@hwnd建议的替代(gsub
- )实现后,我意识到我的原始代码存在什么问题。我快速测试了固定代码并确认了我的想法。我只需要每次后续 replace_str
来电,重新保存结果,由之前的每次调用返回。因此,固定代码如下所示:
# Now we can safely do post-processing, recovering original data
data <- replace_all(data, fixed("!@#"), ": ")
data <- replace_all(data, fixed("@@"), "::")
data <- replace_all(data, fixed("http//"), "http://")
data <- replace_all(data, fixed("mailto@"), "mailto:")
再次感谢@hwnd提出的宝贵建议,这有助于我弄清楚这个问题。