2017-06-07 52 views
0

我试图根据第三个变量重新排列该变量的每个子组内的变量的因子级别,但是我收到一个错误。使用purrr :: map和forcats :: fct_reorder来重新排列每个子组的因子水平

我认识到这是一个有点难以理解的上下文,所以我使用gapminder数据集来说明。在这里,我要重新排序country变量的continent变量的每个类别基础上,pop变量的大小内因子水平:

library(gapminder) 
library(tidyverse) 
library(forcats) 

gapminder %>% 
    filter(year == 2007) %>% 
    group_by(continent) %>% 
    nest() %>% 
    mutate(newdata = map(data, fct_reorder, country, pop)) %>% 
    unnest(newdata) 
Error in mutate_impl(.data, dots) : 
`f` must be a factor (or character vector). 

我在做什么错?

+0

由于'data'是一个data.frame,你需要类似语法'gapminder :: gapminder%>% 过滤器(一年== 2007)%>% GROUP_BY(大陆)%>% 巢() %>% mutate(newdata = map(data,〜mutate(.x,country = forcats :: fct_reorder(country,pop))))%>% unnest(newdata)',但是你仍然有冲突水平问题在下面提到。你应该编辑你的大目标;可能会有更好的方法。 – alistaire

+0

谢谢@alistaire。我现在倾向于在一个单独的载体中“手动”建立因子的水平以完全避免这个问题。 – Phil

+0

反正使用因素有什么意义?除了在图中设置订单或手动设置模型的对比度以外,字符串通常也是一样或更有用。 – alistaire

回答

0

我现在不是真的forcats和它的fct_*功能,我探讨,并没有找到一种方法来实现你想要的。但是我们可以获取它:

library(gapminder) 
library(tidyverse) 

gapminder %>% 
    filter(year == 2007) %>% 
    group_by(continent) %>% 
    nest() %>% 
    mutate(newdata = map(data, ~{ 
    .x$country <- reorder(.x$country, order(.x$pop, decreasing = TRUE)) 
    .x 
    }) 
) -> res 
res 
#> # A tibble: 5 × 3 
#> continent    data   newdata 
#>  <fctr>   <list>   <list> 
#> 1  Asia <tibble [33 × 5]> <tibble [33 × 5]> 
#> 2 Europe <tibble [30 × 5]> <tibble [30 × 5]> 
#> 3 Africa <tibble [52 × 5]> <tibble [52 × 5]> 
#> 4 Americas <tibble [25 × 5]> <tibble [25 × 5]> 
#> 5 Oceania <tibble [2 × 5]> <tibble [2 × 5]> 

我们可以验证因子水平真的变了:

lapply(res$newdata, function(x) as.numeric(x$country)) 
#> [[1]] 
#> [1] 5 7 8 23 3 12 24 31 9 30 15 20 1 21 25 10 18 14 29 33 27 28 4 
#> [24] 6 11 13 26 32 17 22 19 16 2 
#> 
#> [[2]] 
#> [1] 11 29 10 30 16 26 20 22 18 12 21 3 7 23 13 27 2 28 5 8 24 9 19 
#> [24] 4 6 15 1 25 17 14 
#> 
#> [[3]] 
#> [1] 37 15 18 11 44 45 47 24 33 1 50 21 34 28 13 7 5 29 36 2 52 41 30 
#> [24] 51 49 9 22 43 39 6 3 42 27 48 17 8 12 31 26 35 25 20 4 23 19 32 
#> [47] 46 38 10 16 14 40 
#> 
#> [[4]] 
#> [1] 23 3 16 6 1 4 20 25 5 10 12 8 9 2 13 14 11 19 17 7 21 24 18 
#> [24] 15 22 
#> 
#> [[5]] 
#> [1] 1 2 

这个你真的不能unnest它,作为国家因素“名单后“每个continent会与他人发生冲突:

res %>% 
    select(-data) %>% 
    unnest() -> res2 
sapply(res2$country, as.numeric) 
#> [1] 5 7 8 23 3 12 24 31 9 30 15 20 1 21 25 10 18 
#> [18] 14 29 33 27 28 4 6 11 13 26 32 17 22 19 16 2 34 
#> [35] 39 40 43 46 60 62 63 72 73 76 78 84 85 86 87 99 103 
#> [52] 108 112 113 116 120 122 123 126 129 130 135 137 35 36 41 44 47 
#> [69] 48 49 51 52 55 56 57 59 64 67 69 70 71 74 75 77 80 
#> [86] 81 89 90 91 92 93 94 95 96 97 100 101 102 106 107 115 117 
#> [103] 118 119 121 124 125 127 128 131 132 134 136 141 142 37 42 45 50 
#> [120] 53 54 58 61 65 66 68 79 82 83 88 98 105 109 110 111 114 
#> [137] 133 138 139 140 38 104 

我认为他们正在重新排序AG依次。

+0

“之后,你不能真正地拧它,因为每个大陆的因素'列表'会与其他人冲突” 当然......不知道我对这个问题没有想到。嗯,回到绘图板。 – Phil