遍历列并根据每列的分位数过滤掉值

Loop through columns and filter out values based on quantiles for each column

从包含不同站点和大量统计信息的数据框开始...

test_df <- data.frame(site = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J"), stat1 = c(0.44, 11, 0.45, 0, 5, 2, 2.3, 1.8, -3, 0), stat2 = c(10, 9, 10.1, 8, 7, 8.2, 8, 9.5, 9.6, 8), stat3 = c(0, 0.2, 0, 0.1, 0.15, 0.12, 1, -1, 0.15, 0.11))

# site  stat1  stat2  stat3  
#   A    0.44    10     0     
#   B    11      9     0.2    
#   C    0.45    10.1    0
#   D    0       8     0.1
#   E    5       7     0.15
#   F    2       8.2   0.12
#   G    2.3     8      1
#   H    1.8     9.5   -1
#   I    -3      9.6   0.15
#   J    0       8     0.11

我想遍历每个统计数据并输出一个数据帧,其中每个统计数据的唯一值是高于该特定列的第 75 个百分位值或低于第 25 个百分位值的值,这看起来像这样...

# site  stat1  stat2  stat3  
#   A    NA      10     0     
#   B    11      NA     0.2    
#   C    NA      10.1   0
#   D    0       NA     NA
#   E    5       7      NA
#   F    NA      NA     0.12
#   G    2.3     NA     1
#   H    NA      NA     -1
#   I    -3      9.6    NA
#   J    0       NA     NA

这是我目前的方法...


# I know I can filter out values for one stat at a time by doing the following...

stat1_df <- test_df %>% filter(stat1 > quantile(stat1, 0.75) | (stat1 < quantile(stat1, 0.25))) %>% select(site, stat1)

stat1_df

#   site stat1
#   B   11.0
#   D   0.0
#   E   5.0
#   G   2.3
#   I   -3.0
#   J   0.0

但我正在努力做到这一点,所以我可以 automate/loop 通过统计列并使用所有列创建我想要的最终数据框。我将不胜感激任何想法。我将要处理的实际文件有 100 多个统计信息,所以我非常专注于尽可能多地实现自动化。

你可以简单地使用 lapply.

test_df[-1] <- lapply(test_df[-1], function(x) {
  q <- quantile(x, prob=c(.25, .75))
  x[!(x < q[1] | x > q[2])] <- NA
  x
})
test_df
#    site stat1 stat2 stat3
# 1     A    NA  10.0   0.0
# 2     B  11.0    NA   0.2
# 3     C    NA  10.1   0.0
# 4     D   0.0    NA    NA
# 5     E   5.0   7.0    NA
# 6     F    NA    NA    NA
# 7     G   2.3    NA   1.0
# 8     H    NA    NA  -1.0
# 9     I  -3.0   9.6    NA
# 10    J   0.0    NA    NA