我有一个数据框:
> df
ID Chr Start End Rank
1 chr1 213 315 15
2 chr1 416 535 10
3 chr1 1012 1290 12
4 chr1 1899 1987 13
5 chr1 2900 3199 18
6 chr1 3100 3200 10
我想根据平均值之间的距离(小于500)删除行。一个例子将使它更清楚。例如,考虑row1,mean是(Start + End) / 2
,例如(213 + 315)/2 = 264
。现在对于第2行,均值为(416 + 535)/2 = 475.5
。现在这些行的平均值之间的差异小于500 (475.5 - 264)
所以我想保持排名最高的行,在这种情况下,row1将被保留,而2将被删除。第5行和第6行之间也会发生相同的情况,第5行将保留。所以最终的输出将是:
> df
ID Chr Start End Rank
1 chr1 213 315 15
3 chr1 1012 1290 12
4 chr1 1899 1987 13
5 chr1 2900 3199 18
这是dput:
structure(list(ID = 1:6, Chr = structure(c(1L, 1L, 1L, 1L, 1L,
1L), .Label = "chr1", class = "factor"), Start = c(213L, 416L,
1012L, 1899L, 2900L, 3100L), End = c(315L, 535L, 1290L, 1987L,
3199L, 3200L), Rank = c(15L, 10L, 12L, 13L, 18L, 10L)), .Names = c("ID",
"Chr", "Start", "End", "Rank"), class = "data.frame", row.names = c(NA,
-6L))
答案 0 :(得分:1)
我们可以检查均值和测试的差异是否通过条件:
df[c(TRUE, diff(rowMeans(df[,3:4])) > 500),]
# ID Chr Start End Rank
# 1 1 chr1 213 315 15
# 3 3 chr1 1012 1290 12
# 4 4 chr1 1899 1987 13
# 5 5 chr1 2900 3199 18
编辑
要应用条件通过成对,我们可以在tapply
中包含相同的逻辑,并将数据帧分组为多对行。当平均值之差大于500时,我们保留两行,否则我们会删除排名较低的行:
library(dplyr)
df$means <- rowMeans(df[,3:4])
df %>% group_by(grps=gl(nrow(df)/2,2)) %>%
filter(if(diff(means) > 500) TRUE else Rank == max(Rank)) %>% ungroup() %>%
select(-grps, -means)
# Source: local data frame [4 x 5]
#
# ID Chr Start End Rank
# (int) (fctr) (int) (int) (int)
# 1 1 chr1 213 315 15
# 2 3 chr1 1012 1290 12
# 3 4 chr1 1899 1987 13
# 4 5 chr1 2900 3199 18