設置數據:
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