根据平均值的差异从数据框中选择行

时间:2016-07-06 13:38:42

标签: r dataframe

我有一个数据框:

> 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))

1 个答案:

答案 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