关于dplyr::top_n函数选取Top N结果不符合预期的技术咨询
关于
dplyr::top_n的结果疑问 以下是dplyr::top_n的输出情况:
选取Top 2时:
> mtcars %>% dplyr::arrange(desc(mpg)) %>% dplyr::top_n(2, mpg) mpg cyl disp hp drat wt qsec vs am gear carb Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
选取Top 3时:
> mtcars %>% dplyr::arrange(desc(mpg)) %>% dplyr::top_n(3, mpg) mpg cyl disp hp drat wt qsec vs am gear carb Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2 Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
选取Top 4时的问题:
执行以下代码后,结果和Top 3时完全一致:
> mtcars %>% dplyr::arrange(desc(mpg)) %>% dplyr::top_n(4, mpg) mpg cyl disp hp drat wt qsec vs am gear carb Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2 Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
我预期的结果应该包含mpg为27.3的Fiat X1-9:
mpg cyl disp hp drat wt qsec vs am gear carb Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2 Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2 Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
原因解释:
dplyr::top_n的核心逻辑是保留所有观测值中,目标变量值≥第n大的目标变量值的行,而非严格取前n行。
具体到你的例子:
- 取Top 3时,第3大的mpg值是30.4,而有两个观测值的mpg都是30.4,所以这两行都会被保留,最终得到4行结果。
- 取Top 4时,第4大的mpg值仍然是30.4(前3个不同的mpg值为33.9、32.4、30.4),因此所有mpg≥30.4的观测值都会被保留,也就是依然是那4行,不会包含mpg=27.3的行——因为27.3是第4个不同的mpg值,但
top_n不会区分数值的唯一性,只看是否≥第n大的数值。
如果需要严格取排序后的前n行,应该使用dplyr::slice_head(n = 4),或者在arrange后直接用slice(1:4)。
内容的提问来源于stack exchange,提问作者Mohammad Tanvir Ahamed
相关产品推荐
相关产品推荐

