## minimal dfs
df1 <- data.frame(ID=c(rep(1.1, 5),
rep(1.2, 6),
rep(1.3, 3)),
str=unlist(strsplit("aabaaaabcababc", "")), stringsAsFactors=F)
df2 <- data.frame(str=c("a", "b", "a", "b"), stringsAsFactors=F)
## functions
distance <- function(df, query.df, df.col, query.df.col) {
deviating <- df[, df.col] != query.df[, query.df.col]
sum(deviating, na.rm=TRUE) # if too few rows, there will be NA, ignore NA
}
distances <- function(dfs, query.df, dfs.col, query.df.col) {
sapply(dfs, function(df) distance(df, query.df, dfs.col, query.df.col))
}
orderedDistances <- function(dfs, query.df, dfs.col, query.df.col) {
dists <- distances(dfs, query.df, dfs.col, query.df.col)
sort(dists)
}
orderByDistance <- function(dfs, query.df, dfs.col, query.df.col, dfs.split.col) {
dfs.split <- split(dfs, dfs[, dfs.split.col])
dfs.split.N <- lapply(dfs.split, function(df) df[1:nrow(query.df), ])
orderedDistances(dfs.split.N, query.df, dfs.col, query.df.col)
}
orderByDistance(df1, df2, "str", "str", "ID")
# 1.3 1.1 1.2
# 1 3 3
# 1.3 is the closest to df2!
Ваша проблема - это проблема расстояния.Минимизация расстояния = поиск наиболее похожей последовательности.
Этот вид расстояния, который я показываю здесь, предполагает, что при эквивалентных позициях между df2 и sub-df в df1 отклонения учитываются как 1
, а равенство - как 0
.Сумма дает unsimilarity-score
между сравниваемыми фреймами данных - последовательностями строк.
orderByDistance
занимает dfs
(df1) и запрос df (df2), а также столбцы, которые должны сравниваться, истолбец, по которому следует разделить dfs (здесь «ID»).Сначала он разбивает dfs
, затем он собирает N
строк каждого подпрограммы (подготовка к сравнению), а затем применяет orderedDistances
к каждому подпапке с гарантированными N
строками (N = число или строкизапрос df).