如何使用一列对data.frame进行排序?
我正在使用以下内容:
> set.seed(456)
> df1 <- data.frame(col1 = runif(10))
> class(df1)
[1] "data.frame"
> df1 <- df1[order(df1$col1),]
> class(df1)
[1] "numeric"
但是,如果我添加一个空白列,一切正常:
> set.seed(456)
> df1 <- data.frame(col1 = runif(10))
> df1$dummy <- NA
> class(df1)
[1] "data.frame"
> df1 <- df1[order(df1$col1),]
> class(df1)
[1] "data.frame"
> df1
col1 dummy
7 0.08243274 NA
1 0.08955160 NA
2 0.21051232 NA
9 0.23750327 NA
8 0.28552695 NA
6 0.33195997 NA
10 0.38523617 NA
3 0.73295527 NA
5 0.78839789 NA
4 0.85213354 NA
有一个更好的方法吗?
你可以添加drop=FALSE
,它将适用于大多数情况。 [
的默认选项是drop=TRUE
df1[order(df1$col1),, drop=FALSE]
在?`[`的帮助页面中,可以在'Usage'中找到默认参数
x[i, j, ... , drop = TRUE]
以及drop
的描述
drop:对于矩阵和数组。如果为“TRUE”,则结果将强制转换为可能的最低维度(请参阅示例)。这仅适用于提取元素,而不适用于替换元素。有关详细信息,请参阅'drop'。
使用data.table包,您不需要drop = FALSE
:
library(data.table)
setorder(setDT(df1), col1)
这使:
> df1 col1 1: 0.08243274 2: 0.08955160 3: 0.21051232 4: 0.23750327 5: 0.28552695 6: 0.33195997 7: 0.38523617 8: 0.73295527 9: 0.78839789 10: 0.85213354
或者直接在数据帧上而不转换为data.table
:
library(data.table)
setorder(df1, col1)
这使:
> df1 col1 7 0.08243274 1 0.08955160 2 0.21051232 9 0.23750327 8 0.28552695 6 0.33195997 10 0.38523617 3 0.73295527 5 0.78839789 4 0.85213354
您也可以使用dplyr。
library(dplyr)
df1 <- arrange(df1, col1)
class(df1)
[1] "data.frame"
为了资源优化和代码可读性,我建议拆分排序操作:
> positions <- order(df$col1)
# if you want to create a rank: positions <- order(df$col1, decreasing = TRUE)
# and then apply the order without modifying the dataframe
> sorted_df <- df[positions,]