1

为了更改结果数据框中的值,我使用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"

我将不胜感激任何帮助和/或建议。

4

2 回答 2

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"   
于 2014-05-12T12:45:36.907 回答
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 提供的宝贵建议,这些建议帮助我解决了这个问题。

于 2014-05-13T10:27:41.207 回答