2017-09-24 15 views
2

data.frameに2つのカラムがあります。レベルは同じ順序でソートされていなければなりませんが、簡単な方法でそれを行う方法はわかりません。あるコラムから別のコラムへのコピー・ファクタ・レベルの順序

は、ここでの状況です:

library(ggplot2) 
library(dplyr) 
library(magrittr) 
set.seed(1) 
df1 <- data.frame(rating = sample(c("GOOD","BAD","AVERAGE"),10,T), 
        div = sample(c("A","B","C"),10,T), 
        n = sample(100,10,T)) 

# I'm adding a label column that I use for plotting purposes 
df1 <- df1 %>% group_by(rating) %>% mutate(label = paste0(rating," (",sum(n),")")) %>% ungroup 
# # A tibble: 10 x 4 
#  rating div  n   label 
#  <fctr> <fctr> <int>   <chr> 
# 1  BAD  C 48  BAD (220) 
# 2  BAD  B 87  BAD (220) 
# 3  BAD  C 44  BAD (220) 
# 4 GOOD  B 25  GOOD (77) 
# 5 AVERAGE  B  8 AVERAGE (117) 
# 6 AVERAGE  C 10 AVERAGE (117) 
# 7 AVERAGE  A 32 AVERAGE (117) 
# 8 GOOD  B 52  GOOD (77) 
# 9 AVERAGE  C 67 AVERAGE (117) 
# 10  BAD  C 41  BAD (220) 

# rating levels are sorted 
df1$rating <- factor(df1$rating,c("BAD","AVERAGE","GOOD")) 

ggplot(df1,aes(x=rating,y=n,fill=div)) + geom_col() # plots in the order I want 
ggplot(df1,aes(x=label,y=n,fill=div)) + geom_col() # doesn't because levels aren't sorted 

私は1つの列から別の要因順序をコピーするために管理するにはどうすればよいですか? 私はそれがこのように動作させることができますが、私はそれは本当に厄介だと思う:あなたはaes(x = ratingに固執し、scale_x_discretelabelsを作成することができ

lvls <- df1 %>% select(rating,label) %>% unique %>% arrange(rating) %>% extract2("label") 
df1$label <- factor(df1$label,lvls) 
ggplot(df1,aes(x=label,y=n,fill=div)) + geom_col() 

答えて

3

、あなたはのレベルを設定するforcatsを使用することができますこのようなratingの順序によって...

library(forcats) 
df1 <- df1 %>% group_by(rating) %>% 
       mutate(label=paste0(rating," (",sum(n),")")) %>% 
       ungroup %>% 
       arrange(rating) %>%    #sort by rating 
       mutate(label=fct_inorder(label)) #set levels by order in which they appear 

それとも、同じことを行うためにforcats::fct_reorderを使用することができます...

df1$label <- fct_reorder(df1$label, as.numeric(df1$rating)) 

プロットは、正しい順序でバーを持っています。

+1

ありがとうございます、このパッケージは面白いです。私は関数fct_reorderを見つけました。これはあまり控えめなアプローチです: 'df1 $ label < - fct_reorder(df1 $ label、as.numeric(df1 $ rating))'。たぶんあなたはあなたの答えにそれを加えることができますか? –

+0

ありがとうございます! –

3

代わりのラベル列を追加し、aes(x = labelを使用します。

ggplot(df1, aes(x = rating, y = n, fill = div)) + 
    geom_col() + 
    scale_x_discrete(labels = df1 %>% 
        group_by(rating) %>% 
        summarize(n = sum(n)) %>% 
        mutate(lab = paste0(rating, " (", n, ")")) %>% 
        pull(lab)) 
あなたが ratingのレベルを設定したら

enter image description here

関連する問題