如何在R中对数据框进行排序和筛选?

18

我知道如何排序数据框:

df[order(df$Height),]

我也知道如何根据某个条件过滤(或子集化)数据框:

df[df$Weight > 120,]

但是,我该如何同时进行排序和筛选呢?(例如按身高排序并按体重筛选)?

3个回答

15

可以分为两个步骤

 df1 <- df[df$weight > 120, ]
 df2 <- df1[order(df1$height), ]

或者,如果你必须要一步完成,但这真的没有更清晰。

首先是数据:

R> set.seed(42)
R> df <- data.frame(weight=rnorm(10, 120, 10), height=rnorm(10, 160, 20))
R> df
   weight height
1   133.7  186.1
2   114.4  205.7
3   123.6  132.2
4   126.3  154.4
5   124.0  157.3
6   118.9  172.7
7   135.1  154.3
8   119.1  106.9
9   140.2  111.2
10  119.4  186.4

其中一种方法是进行双重子集:

R> subset(df, weight > 120)[order(subset(df, weight > 120)$height),]
  weight height
9  140.2  111.2
3  123.6  132.2
7  135.1  154.3
4  126.3  154.4
5  124.0  157.3
1  133.7  186.1
R> 

我会选择两步走。


我一直在等待适当的 Hadley-isms :-) - Dirk Eddelbuettel
@DirkEddelbuettel @mrdwab 当然我知道。我会说为什么是42,而不是12 - kohske
1
这是对《银河系漫游指南》的轻微文化参考。 - Dirk Eddelbuettel
@kohske 这是我的猜测:Dirk在他的.Rprofile中恰好有一个全局的set.seed(88),然后为SO生成了一个随机种子s = sample(1:100, 1) ; set.seed(s) - baptiste
@baptiste 不,42才是答案 ;-p 我喜欢它。我会遵循它。谢谢。 - kohske
显示剩余6条评论

12

使用data.table包可以让你在一行代码中完成此操作:

借鉴Dirk Eddelbuettel的示例,设置一些数据:

set.seed(42)
df <- data.frame(weight=rnorm(10, 120, 10), height=rnorm(10, 160, 20))

data.frame转换为data.table,并按重量对其进行子集划分,按高度排序:

library(data.table)
dt <- data.table(df)

dt[weight>120][order(height)]

       weight   height
[1,] 140.1842 111.1907
[2,] 123.6313 132.2228
[3,] 135.1152 154.3149
[4,] 126.3286 154.4242
[5,] 124.0427 157.3336
[6,] 133.7096 186.0974

很好。是的,这是data.table的一个关键便利功能之一。不过我想知道新用户是否认为他们必须一直转换才能使用data.table呢?在这种情况下和许多其他情况下,可以用data.table()替换对data.frame()的调用,而且在一开始就使用data.table时无需转换。我知道你知道这一点,这只是一个市场营销问题。 - Matt Dowle

8
df1 <- df[order(df$height), ][df$weight > 120, ]

请确保在过滤器之前放置订单。


对我来说不起作用:答案中的$weight小于120。 - jubilatious1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接