在我的数据中,我有多行只是彼此略有不同,例如0.001。如果发生这种情况,我想只保留1条记录。是否存在可以进行逐行比较的现有函数/包,如果差异小于给定的阈值epsilon,则删除行?我在想distinct(., epsilon = 0.001)
示例:
df <- data.frame(
IDname = c("aaa1", "bbb2", "ccc3", "ddd4"),
g = c(0.00501, 0.00499, 2, 2),
t = c(0.005002, 0.004991, 2.001, 2.0001),
x = c(1.0001, 1, 2, 2.00001)
)
df
期望的输出:
IDname g t x
1 aaa1 0.00501 0.005002 1.00010
3 ccc3 2.00000 2.001000 2.00000
答案 0 :(得分:2)
为什么没有round
值+ unique
?
df <- data.frame(
g = c(1.001, 1, 2.00001, 2),
t = c(1, 1.001, 2.001, 2.0001),
x = c(1.0001, 1, 2, 2.00001)
)
vect <- sapply(df, function(x) unique(round(x, 2)) )
data.frame(vect)
仅当每列的长度相等时才有效。
答案 1 :(得分:1)
假设OP的示例中存在错误(请参阅上面的评论),这是使用duplicated
d行值paste
的解决方案。
如果OP澄清并且我误解了这个问题,将会删除。
# Your data
df <- data.frame(
IDname = c("aaa1", "bbb2", "ccc3", "ddd4"),
g = c(0.00501, 0.00499, 2, 2),
t = c(0.005002, 0.004991, 2.001, 2.0001),
x = c(1.0001, 1, 2, 2.00001)
)
df[!duplicated(apply(round(df[, -1], 3), 1, paste, collapse = "_")), ];
# IDname g t x
#1 aaa1 0.00501 0.005002 1.00010
#3 ccc3 2.00000 2.001000 2.00000
#4 ddd4 2.00000 2.000100 2.00001
更常见的是对任何容差epsilon
:
epsilon <- 0.0001;
df[!duplicated(apply(round(df[, -1], -log10(epsilon) - 1), 1, paste, collapse = "_")), ];
使用分层聚类的方法(受@BenoitLondon启发)
我们可以使用欧几里德距离矩阵进行层次聚类,并通过相似性完成与聚类观测(行)的联系。
# Calculate euclidean distance matrix
dist <- dist(df[, -1], method = "euclidean");
# Perform hierarchical clustering with complete linkage
hc <- hclust(dist, method = "complete");
我们现在可以通过识别dmax = sqrt(sum_m epsilon^2) = sqrt(m) * epsilon
给出两个相似观察值之间的最大欧氏距离来切割树,其中m
是(数字)列的数量。因此,我们可以在h = dmax
高度剪切树。
# Cut the tree
epsilon <- 0.0001;
grp <- cutree(hc, h = sqrt(ncol(df[, -1])) * epsilon);
grp;
#[1] 1 1 2 3
然后折叠dataframe
df[!duplicated(grp), ];
# IDname g t x
#1 aaa1 0.00501 0.005002 1.00010
#3 ccc3 2.00000 2.001000 2.00000
#4 ddd4 2.00000 2.000100 2.00001