给定一个数据框,我想使用来过滤每列,使用每列的分位数,我更喜欢使用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
我期望的结果将是1.长格式的数据框,其中任何高于百分位数的内容设置为NA或完全删除,或2.宽格式的数据框,其中任何高于百分位数的内容设置为NA。
2条答案
按热度按时间lqfhib0f1#
我认为最简单的方法是转换成一个长形状,并使用
x1
、x2
和x3
作为计算分位数的组,然后如果愿意,可以将其拉伸回宽形状,可以将高值显式替换为NA
,但如果使用tidyr::spread
,你还是会得到NA
s来填充缺失的值。为了清晰起见,我保留了一些中间步骤,但要点是将
gather
变成一个长形状,找到第95个百分位数,将值保持在第95个百分位数或以下,然后将spread
变回宽。分组后,我还添加了一个行号作为ID列,以避免可怕的“重复名称...”错误。对于分位数,它如下所示:从前面几行可以看到,第10行的值高于对应的第95百分位数,因此我们希望将其过滤掉,并转换为
NA
。然后使用分位数进行过滤和扩散。
实际上,不需要仅为
q95
添加整列,而可以使用更简洁的列,如filter(value <= quantile(value, 0.95))
。c9qzyr3d2#
从2021年起,
filter
与if_all
配合使用: