设置数据:
x=c("xxx", "xxx", "xxx1", "xx1x", "yyyy", "gggg")
代码:
same <- sapply(seq(length(x)-1),
function(i)any(agrep(x[i+1], x[1], max.distance=0.25)))
ex <- embed(x, 2)
cbind(A=x, B=c(x[1], ifelse(same, ex[, 2], ex[, 1])))
结果:
A B
[1,] "xxx" "xxx"
[2,] "xxx" "xxx"
[3,] "xxx1" "xxx"
[4,] "xx1x" "xxx1"
[5,] "yyyy" "yyyy"
[6,] "gggg" "gggg"
为什么它的工作?
一些关键概念和真的有用的功能:
首先,agrep
提供了测试多么相似字符串,使用Levenshtein edit distance
,有效计数,将一个字符串转换到另一个需要个性变化的数量。参数max.distance=0.25
意味着25%的模式字符串允许不同。
例如,测试是否有任何原始字符串的类似于“XXX”:此返回1:4:
agrep("xxx", x, max.distance=0.25)
[1] 1 2 3 4
其次,embed
提供的测试滞后变量的有用方法。例如,embed(x, 2) turns
x`成为一个滞后数组。这使得很容易对x [1]比较对x [2],因为它们现在都在同一行上的阵列中:
embed(x, 2)
[,1] [,2]
[1,] "xxx" "xxx"
[2,] "xxx1" "xxx"
[3,] "xx1x" "xxx1"
[4,] "yyyy" "xx1x"
[5,] "gggg" "yyyy"
最后,我使用cbind
和矢量子集来缝合在一起的原始矢量和新的矢量。
为了使一个数据帧,而不是一个矢量在此工作中,我把码成一个函数,如下所示:
df <- data.frame(A=c("xxx", "xxx", "xxx1", "xx1x", "yyyy", "gggg"))
f <- function(x){
x <- as.vector(x)
same <- sapply(seq(length(x)-1),
function(i)any(agrep(x[i+1], x[1], max.distance=0.25)))
ex <- embed(x, 2)
c(x[1], ifelse(same, ex[, 2], ex[, 1]))
}
df$B <- f(df$A)
df
A B
1 xxx xxx
2 xxx xxx
3 xxx1 xxx
4 xx1x xxx1
5 yyyy yyyy
6 gggg gggg
等等,OP没有要B下的第四个条目是'xx1x'吗? – joran
是的,他做到了,但他也承认他猜到了这个价值。 'agrep'使用正式的变化意义定义,并且默认配置为将所有的修改,删除和插入计数为一次。因此在这个例子中有两个变化。这可以在'agrep'的参数中进行一定程度的配置。有关详细信息,请参阅'?agrep'。 – Andrie
啊,我明白了。谢谢! – joran