2017-09-24 2 views
2

ich zwei Spalten in einer data.frame habe, die Ebene sortierten in der gleichen Reihenfolge haben sollte, aber ich weiß nicht, wie es auf einfache Art und Weise zu tun.kopieren Faktor Ebene, um von einer Spalte zu einem anderen

Hier ist die Situation:

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 

Wie schaffe ich es, den Faktor, um von einer Spalte in eine andere zu kopieren? Ich kann es auf diese Weise funktioniert, aber ich denke, es ist wirklich peinlich:

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() 

Antwort

3

Sobald Sie die Ebenen der rating eingestellt haben, können Sie forcats verwenden, um die Ebenen vonzu setzendurch die Reihenfolge der rating so ...

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 

Oder Sie forcats::fct_reorder verwenden können, das Gleiche zu tun ...

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

Das Grundstück hat dann die Bars in der richtigen Reihenfolge.

+1

Vielen Dank, dieses Paket ist interessant, erkunde ich fand die Funktion 'fct_reorder', die einen weniger ausführlichen Ansatz erlaubt:' df1 $ label <- fct_reorder (df1 $ label, as.numeric (df1 $ rating)) '. Vielleicht könnten Sie es zu Ihrer Antwort hinzufügen? –

+0

Danke - wirst du tun! –

3

Statt eine Beschriftungsspalte hinzuzufügen und verwenden aes(x = label, können Sie aes(x = rating halten, und erstellen Sie die labels in scale_x_discrete:

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)) 

enter image description here

Verwandte Themen