我有这样一个 Dataframe :
mydf <- data.frame(A = c(40,9,55,1,2), B = c(12,1345,112,45,789))
mydf
A B
1 40 12
2 9 1345
3 55 112
4 1 45
5 2 789
我只想保留95%的观测值,并丢弃5%具有极值的数据。首先,我计算它们有多少个观测值:
th <- length(mydf$A) * 0.95
然后我想删除th
上面的所有行(或者保留th
下面的行,根据您的需要),我需要按升序对mydf
排序,以便只删除那些极值。
mydf[order(mydf["A"], mydf["B"]),]
mydf[order(mydf$A,mydf$B),]
mydf[with(mydf, order(A,B)), ]
plyr::arrange(mydf,A,B)
但是没有任何效果,所以mydf
没有同时按两列升序排序。我看了这里Sort (order) data frame rows by multiple columns,但是最常见的解决方案不起作用,我不知道为什么。
然而,如果我一次只考虑一列(例如A
),这些排序方法可以工作,但是我不知道如何丢弃极值,因为:
mydf <- mydf[(order(mydf$A) < th),]
删除值为9的第二行,而我的意图是对mydf进行子集化,只保留th
reshold以下的值(在本例中是指观察数,而不是值)。我可以想象,我缺少的是非常简单和基本的东西......而且可能有更好的tidyverse
方法。
2条答案
按热度按时间kcwpcxri1#
我认为这里需要 *
rank
,但是它不能用于多列。要解决这个问题,请注意rank(.)
等价于order(order(.))
:这样,我们就可以在两列(所有列)上使用
order
,然后再次排序,再将得到的排名与th
值进行比较。这种方法的优点是保留了行的自然排序。
如果您希望只调用一次
order
,那么可以重新排序并使用head
:尽管这不会保留行的原始顺序(这对您可能重要,也可能不重要)。
wrrgggsh2#
可能的方法
另一种方法是使用dplyr排名函数,如
cume_dist()
或percent_rank()
,它们可以接受 Dataframe 作为输入,并返回基于所有列的排名/百分点。关于分位数的一般注意事项
更一般地说,请记住,定义分位数是不容易的,比如are multiple possible approaches。你需要考虑一下在给定目标的情况下,什么是最有意义的。举个例子,从dplyr docs:
cume_dist(x)
计算小于或等于x_i
的值的总数,并将其除以观测数。percent_rank(x)
计算小于x_i
的值的总数,并将其除以观测数减去1
。这意味着,对于
cume_dist()
,最小值总是1 / nrow()
,而对于percent_rank()
,最大值总是1
,这意味着根据方法的不同,可能会排除不同的情况,也意味着我提供的代码将 * 总是 * 删除排名最高的行。这可能符合也可能不符合你的期望。(例如,在一个只有5个元素的向量中,最高值是“高于第95百分位数”吗?这取决于你如何定义它。)