2017-07-31 58 views
1

我可以选择和安排单列toplists:如何获得多列

iris %>% 
    select(Petal.Width, Species) %>% 
    arrange(desc(Petal.Width)) 

但我要为整个数据框做到这一点。我用forloop来解决这个问题:

features <- colnames(iris) 
top <- data.frame() 
for (i in 1:length(features)) { 
    label <- features[[i]] 
    iris %>% 
    select(label, Species) %>% 
    arrange(desc(label)) %>% 
    top_n(3) %>% 
    rbind(top) 
} 
# Error in arrange_impl(.data, dots) : 
# incorrect size (1) at position 1, expecting : 150 

哪给了我一个错误。

显然arrange(desc(label))不起作用。我搜索周围,并尝试像UQsubstitute的东西来取消label,但没有结果。

rbind(top)top_n末也可能是我想不完全是,但我现在的主要问题是如何使用label所以for循环西港岛线接受它。

也许有人知道一个更好的办法产品总数比我的for循环...

所需的输出是一个数据帧,每列前3位。

回答

2

如果你想在所有列上使用某些东西,有多种方式。我首先想要gather(或融化)数据,然后再使用dplyr。

例如,在你的情况,这将导致


library(tidyr) 
library(dplyr) 

iris %>% 
    gather("var", "val", -Species) %>% 
    group_by(var) %>% 
    arrange(desc(val)) %>% 
    top_n(3) 
#> Selecting by val 
#> # A tibble: 14 x 3 
#> # Groups: var [4] 
#>  Species   var val 
#>  <fctr>  <chr> <dbl> 
#> 1 virginica Sepal.Length 7.9 
#> 2 virginica Sepal.Length 7.7 
#> 3 virginica Sepal.Length 7.7 
#> 4 virginica Sepal.Length 7.7 
#> 5 virginica Sepal.Length 7.7 
#> 6 virginica Petal.Length 6.9 
#> 7 virginica Petal.Length 6.7 
#> 8 virginica Petal.Length 6.7 
#> 9 setosa Sepal.Width 4.4 
#> 10 setosa Sepal.Width 4.2 
#> 11 setosa Sepal.Width 4.1 
#> 12 virginica Petal.Width 2.5 
#> 13 virginica Petal.Width 2.5 
#> 14 virginica Petal.Width 2.5 

你所看到的是,top_n选择前N个值不前n项,但您可以替换slice(1:3)的功能

这是否给你你在哪里寻找?

+1

很好的答案。小调:如果使用“slice(1:3)”选择每个组中的前3个条目,则结果可以通过'spread'进一步传递,以便将数据帧恢复为原始宽格式。 –

+2

很高兴喜欢它。为了再次传播这些值,我们必须携带某种标识符,否则传播将停止,因为我们有重复的标识符......但是否则您是正确的。 – David

+0

是的,这工作!非常感谢! – raoul