2017-06-07 55 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