【问题标题】:Rank variable by group (dplyr)按组对变量进行排名 (dplyr)
【发布时间】:2016-04-30 07:12:57
【问题描述】:

我有一个包含 x1, x2, group 列的数据框,我想生成一个新的数据框,其中包含一个额外的列 rank,该列指示 x1 在其组中的顺序。

有一个相关问题here,但接受的答案似乎不再有效。

到这里为止,没关系:

library(dplyr)
data(iris)
by_species <- iris %>% 
              arrange(Species, Sepal.Length) %>% 
              group_by(Species)  

但是当我尝试按组获得排名时:

by_species <- mutate(by_species, rank=row_number())

错误是:

排名错误(x, ties.method = "first", na.last = "keep") :
缺少参数“x”,没有默认值

更新

问题是dplyrplyr 之间存在冲突。要重现错误,请加载两个包:

library(dplyr)
library(plyr)
data(iris)
by_species <- iris %>% 
              arrange(Species, Sepal.Length) %>% 
              group_by(Species) %>% 
              mutate(rank=row_number())
# Error in rank(x, ties.method = "first", na.last = "keep") : 
# argument "x" is missing, with no default

卸载plyr 它可以正常工作:

detach("package:plyr", unload=TRUE)
by_species <- iris %>% 
              arrange(Species, Sepal.Length) %>% 
              group_by(Species) %>% 
              mutate(rank=row_number())

by_species %>% filter(rank <= 3)

##   Sepal.Length Sepal.Width Petal.Length Petal.Width    Species  rank
##          (dbl)       (dbl)        (dbl)       (dbl)     (fctr) (int)
## 1          4.3         3.0          1.1         0.1     setosa     1
## 2          4.4         2.9          1.4         0.2     setosa     2
## 3          4.4         3.0          1.3         0.2     setosa     3
## 4          4.9         2.4          3.3         1.0 versicolor     1
## 5          5.0         2.0          3.5         1.0 versicolor     2
## 6          5.0         2.3          3.3         1.0 versicolor     3
## 7          4.9         2.5          4.5         1.7  virginica     1
## 8          5.6         2.8          4.9         2.0  virginica     2
## 9          5.7         2.5          5.0         2.0  virginica     3

【问题讨论】:

  • 你确定命令by_species &lt;- mutate(by_species, rank=row_number()) 是产生错误的那个吗?它对我有用,您的错误指的是 rank 函数,而不是正在使用的 row_number 函数。此外,如果您使用rank,则需要提供rank(x) 中的参数(其中x 是您想要排名的)。 row_number 不需要这个。
  • 嗯不,我不确定... :O
  • 我使用rank时不会报错:by_species &lt;- mutate(by_species, myrank=rank(Sepal.Length))
  • @steveb loading plyr 然后dplyr 它似乎在我的电脑上不起作用
  • 我还发现我的需要使用detach("package:plyr", unload=TRUE)才能正常运行。

标签: r dplyr


【解决方案1】:

以下会产生指定的预期结果。

library(dplyr)

by_species <- iris %>% arrange(Species, Sepal.Length) %>%
    group_by(Species) %>% 
    mutate(rank = rank(Sepal.Length, ties.method = "first"))

by_species %>% filter(rank <= 3)
##Source: local data frame [9 x 6]
##Groups: Species [3]
##
##  Sepal.Length Sepal.Width Petal.Length Petal.Width    Species  rank
##         (dbl)       (dbl)        (dbl)       (dbl)     (fctr) (int)
##1          4.3         3.0          1.1         0.1     setosa     1
##2          4.4         2.9          1.4         0.2     setosa     2
##3          4.4         3.0          1.3         0.2     setosa     3
##4          4.9         2.4          3.3         1.0 versicolor     1
##5          5.0         2.0          3.5         1.0 versicolor     2
##6          5.0         2.3          3.3         1.0 versicolor     3
##7          4.9         2.5          4.5         1.7  virginica     1
##8          5.6         2.8          4.9         2.0  virginica     2
##9          5.7         2.5          5.0         2.0  virginica     3

by_species %>% slice(1:3)
##Source: local data frame [9 x 6]
##Groups: Species [3]
##
##  Sepal.Length Sepal.Width Petal.Length Petal.Width    Species  rank
##         (dbl)       (dbl)        (dbl)       (dbl)     (fctr) (int)
##1          4.3         3.0          1.1         0.1     setosa     1
##2          4.4         2.9          1.4         0.2     setosa     2
##3          4.4         3.0          1.3         0.2     setosa     3
##4          4.9         2.4          3.3         1.0 versicolor     1
##5          5.0         2.0          3.5         1.0 versicolor     2
##6          5.0         2.3          3.3         1.0 versicolor     3
##7          4.9         2.5          4.5         1.7  virginica     1
##8          5.6         2.8          4.9         2.0  virginica     2
##9          5.7         2.5          5.0         2.0  virginica     3

【讨论】:

  • 这个问题要求dplyr 解决方案,所以我在此评论中添加了data.table 解决方案,因为它可能有用。以下将使用data.tablesetDT(iris)[order(Species, Sepal.Length), .SD[1:3], by = Species]
【解决方案2】:

对于未来的读者,可以使用基数 R 来实现按组变量的排名。根据 OP 的 iris 数据示例,根据 Sepal.Length 进行排名:

# ORDER BY SPECIES AND SEPAL.LENGTH
iris <- iris[with(iris, order(Species, Sepal.Length)), ]

# RUN A ROW COUNT FOR RANK BY SPECIES GROUP
iris$rank <- sapply(1:nrow(iris), 
                    function(i) sum(iris[1:i, c('Species')]==iris$Species[i]))

# FILTER DATA FRAME BY TOP 3
iris <- iris[iris$rank <= 3,]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-28
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多