给定一个数据框,我想使用每列的分位数来过滤每列。我更喜欢使用 dplyr/tidyverse 来完成此任务。
set.seed(23)
df <- data.frame(
x1 = runif(10, 0, 100),
x2 = runif(10, 0, 100),
x3 = runif(10, 0, 100)
)
df
> df
x1 x2 x3
1 57.66037 86.59590 58.63978
2 22.30729 70.14217 27.47410
3 33.18966 39.04731 14.76570
4 71.07246 31.47697 80.14103
5 81.94490 84.59473 38.64098
6 42.37206 13.92785 82.04507
7 96.35445 51.81206 68.49373
8 97.81304 59.35508 88.33893
9 84.05219 94.24617 11.19208
10 99.66112 62.80196 77.88340
> quantile(df$x1, .95)
95%
98.82949
> quantile(df$x2, .95)
95%
90.80355
Run Code Online (Sandbox Code Playgroud)
我想要的结果将是 1. 一个长格式的数据帧,其中百分位数以上的任何内容设置为 NA 或完全删除,或者 2. 一个宽数据帧,其中百分位数以上的任何内容设置为 NA。
我认为执行这些操作的最简单方法是转换为长形状并使用x1、x2和x3作为计算分位数的组。然后,如果您愿意,可以将其拉伸回宽形状。您可以显式地用 替换高值NA,但如果您使用tidyr::spread,则NA无论如何都会填充缺失值。
为了清楚起见,我保留了一些中间步骤,但要点是gather形成一个长形状,找到第 95 个百分位数,将值保持在第 95 个百分位数或低于第 95 个百分位数,然后spread返回到宽形状。分组后,我还添加行号作为 ID 列,以避免可怕的“重复名称...”错误。对于分位数,它看起来像这样:
library(tidyverse)
...
df %>%
gather(key, value) %>%
group_by(key) %>%
mutate(q95 = quantile(value, 0.95), row = row_number())
#> # A tibble: 30 x 4
#> # Groups: key [3]
#> key value q95 row
#> <chr> <dbl> <dbl> <int>
#> 1 x1 57.7 98.8 1
#> 2 x1 22.3 98.8 2
#> 3 x1 33.2 98.8 3
#> 4 x1 71.1 98.8 4
#> 5 x1 81.9 98.8 5
#> 6 x1 42.4 98.8 6
#> 7 x1 96.4 98.8 7
#> 8 x1 97.8 98.8 8
#> 9 x1 84.1 98.8 9
#> 10 x1 99.7 98.8 10
#> # ... with 20 more rows
Run Code Online (Sandbox Code Playgroud)
您可以从前几行看到,第 10 行的值高于相应的第 95 个百分位数,因此我们希望该值被过滤掉并转换为NA.
然后使用分位数进行过滤和扩散。
df %>%
gather(key, value) %>%
group_by(key) %>%
mutate(q95 = quantile(value, 0.95), row = row_number()) %>%
filter(value <= q95) %>%
select(-q95) %>%
spread(key, value) %>%
select(-row)
#> # A tibble: 10 x 3
#> x1 x2 x3
#> <dbl> <dbl> <dbl>
#> 1 57.7 86.6 58.6
#> 2 22.3 70.1 27.5
#> 3 33.2 39.0 14.8
#> 4 71.1 31.5 80.1
#> 5 81.9 84.6 38.6
#> 6 42.4 13.9 82.0
#> 7 96.4 51.8 68.5
#> 8 97.8 59.4 NA
#> 9 84.1 NA 11.2
#> 10 NA 62.8 77.9
Run Code Online (Sandbox Code Playgroud)
在实践中,您不需要仅为 添加一整列q95,而是可以使用更简洁的内容,例如filter(value <= quantile(value, 0.95))。
| 归档时间: |
|
| 查看次数: |
5257 次 |
| 最近记录: |