Настроить данные:
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