[英]R: Compute the row-wise similarity for a dataframe and sort data out based on that similarity
[英]Prune a dataframe based on row-wise column similarity in R
我有一個非常大的 dataframe 基因組位點,其基因型得分為 0、1 或 2。這是我認為解決問題的一個非常小的樣本:
x1 x2 x3 x4
0 0 1 0
0 0 1 0
1 1 2 1
1 1 1 1
2 2 0 1
2 2 1 2
基因座 x1 和 x2 相同,而 x4 高度相似。 我希望實現的是創建一個 function,或使用已經存在的一個,為我的每個位點按行分配相似性分數,然后根據我設置的閾值相似性修剪數據集。
例如,如果我將閾值設置為 1 (100%),它只會修剪 x1 和 x2,因為它們是重復的——我知道該怎么做。 但是,如果我將閾值設置為 0.8,即相似度為 80%,那么除了 x1 和 x2 之外,它還會修剪 x4。
重要的是 function 作用於逐行相似性,而不只是比較具有相似分布的 0、1 和 2 的列。
以下是我將如何處理這個問題。
首先,獲取列名的所有唯一配對的列表:
pairs <- expand.grid(names(df), names(df))
pairs <- pairs[lower.tri(replicate(length(df), names(df))),]
pairs
#> Var1 Var2
#> 2 x2 x1
#> 3 x3 x1
#> 4 x4 x1
#> 7 x3 x2
#> 8 x4 x2
#> 12 x4 x3
現在遍歷它以比較原始數據集中每對唯一列中相同行的比例。 這為每個列對提供了 0 到 1 之間的相似性分數:
pairs$similarity <- apply(pairs, 1, function(x) sum(df[x[1]] == df[x[2]])/nrow(df))
pairs
#> Var1 Var2 similarity
#> 2 x2 x1 1.0000000
#> 3 x3 x1 0.1666667
#> 4 x4 x1 0.8333333
#> 7 x3 x2 0.1666667
#> 8 x4 x2 0.8333333
#> 12 x4 x3 0.1666667
現在刪除此列表中相似度得分低於您選擇的閾值的所有行(我們將在此處設為 0.8)
pairs <- pairs[which(pairs$similarity > 0.8),]
pairs
#> Var1 Var2 similarity
#> 2 x2 x1 1.0000000
#> 4 x4 x1 0.8333333
#> 8 x4 x2 0.8333333
現在我們提取Var1
和Var2
中的所有唯一列名稱,因為這些列與至少一個其他列相似:
keep_cols <- as.character(sort(unique(c(pairs$Var1, pairs$Var2))))
#> [1] "x1" "x2" "x4"
我們使用它對原始數據框進行子集化以獲得我們想要的結果:
df[match(keep_cols, names(df))]
#> x1 x2 x4
#> 1 0 0 0
#> 2 0 0 0
#> 3 1 1 1
#> 4 1 1 1
#> 5 2 2 1
#> 6 2 2 2
當然,您可以將所有這些都放在 function 中,以便更輕松地調整閾值並迭代應用:
remove_dissimilar <- function(df, threshold = 0.8) {
pairs <- expand.grid(names(df), names(df))
pairs <- pairs[lower.tri(replicate(length(df), names(df))),]
pairs$similarity <- apply(pairs, 1, function(x) {
sum(df[x[1]] == df[x[2]])/nrow(df)})
pairs <- pairs[which(pairs$similarity > threshold),]
keep_cols <- as.character(sort(unique(c(pairs$Var1, pairs$Var2))))
df[match(keep_cols, names(df))]
}
所以現在你可以這樣做:
remove_dissimilar(df, 0.8)
#> x1 x2 x4
#> 1 0 0 0
#> 2 0 0 0
#> 3 1 1 1
#> 4 1 1 1
#> 5 2 2 1
#> 6 2 2 2
remove_dissimilar(df, 0.9)
#> x1 x2
#> 1 0 0
#> 2 0 0
#> 3 1 1
#> 4 1 1
#> 5 2 2
#> 6 2 2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.