Ggplot2 बार ग्राफ में बार्स ऑर्डर करें


301

मैं एक बार ग्राफ बनाने की कोशिश कर रहा हूं जहां सबसे बड़ा बार y अक्ष के सबसे करीब होगा और सबसे छोटा बार सबसे दूर होगा। तो यह उस तरह की तालिका है जैसे मेरे पास है

    Name   Position
1   James  Goalkeeper
2   Frank  Goalkeeper
3   Jean   Defense
4   Steve  Defense
5   John   Defense
6   Tim    Striker

इसलिए मैं एक बार ग्राफ बनाने की कोशिश कर रहा हूं जो स्थिति के अनुसार खिलाड़ियों की संख्या दिखाएगा

p <- ggplot(theTable, aes(x = Position)) + geom_bar(binwidth = 1)

लेकिन ग्राफ गोलकीपर बार पहले तो बचाव, और अंत में स्ट्राइकर एक दिखाता है। मैं चाहता हूं कि ग्राफ को आदेश दिया जाए ताकि डिफेंस बार y अक्ष के सबसे करीब हो, गोलकीपर एक, और अंत में स्ट्राइकर एक। धन्यवाद


12
टेबल के साथ गड़बड़ करने के लिए (या डेटाफ़्रेम) के बिना ggplot उन्हें आपके लिए पुनः व्यवस्थित नहीं कर सकता?
tumultous_rooster

1
@ मैटो'ब्रायन मुझे यह अविश्वसनीय लगता है कि यह एक एकल, साधारण कमांड में नहीं किया जाता है
Euler_Salter

@Zimano बहुत बुरा है जो आप मेरी टिप्पणी से प्राप्त कर रहे हैं। मेरा अवलोकन ggplot2ओपी के रचनाकारों के प्रति था
Euler_Salter

2
@Euler_Salter स्पष्ट करने के लिए धन्यवाद, मेरी तरह आप पर कूदने के लिए ईमानदारी से माफी। मैंने अपनी मूल टिप्पणी हटा दी है।
ज़िमानो

जवाबों:


214

ऑर्डर करने की कुंजी यह है कि आप जिस ऑर्डर को चाहते हैं, उसमें कारक के स्तर को सेट करें। एक आदेशित कारक की आवश्यकता नहीं है; एक आदेशित कारक में अतिरिक्त जानकारी आवश्यक नहीं है और यदि ये डेटा किसी भी सांख्यिकीय मॉडल में उपयोग किए जा रहे हैं, तो गलत पैराट्रिमेशन हो सकता है - इस तरह के नाममात्र डेटा के लिए बहुपद विरोधाभास सही नहीं हैं।

## set the levels in order we want
theTable <- within(theTable, 
                   Position <- factor(Position, 
                                      levels=names(sort(table(Position), 
                                                        decreasing=TRUE))))
## plot
ggplot(theTable,aes(x=Position))+geom_bar(binwidth=1)

बैंगन का आंकड़ा

सबसे सामान्य अर्थों में, हमें केवल वांछित क्रम में होने के लिए कारक स्तरों को निर्धारित करने की आवश्यकता है। यदि अनिर्दिष्ट छोड़ दिया जाता है, तो एक कारक का स्तर वर्णानुक्रम में हल किया जाएगा। आप ऊपर दिए गए कारक के रूप में कॉल के भीतर स्तर के आदेश को भी निर्दिष्ट कर सकते हैं, और अन्य तरीके भी संभव हैं।

theTable$Position <- factor(theTable$Position, levels = c(...))

1
@ गेविन: 2 सरलीकरण: चूंकि आप पहले से ही उपयोग कर रहे हैं within, इसलिए उपयोग करने की कोई आवश्यकता नहीं है theTable$Position, और आप केवल sort(-table(...))घटते क्रम के लिए कर सकते हैं ।
प्रसाद छलासनी

2
@ प्रसाद पूर्व में परीक्षण से बचा हुआ था, इसलिए इसे इंगित करने के लिए धन्यवाद। जहां तक ​​बाद की बात है, मैं स्पष्ट रूप से -आपके द्वारा उपयोग किए गए की तुलना में उल्टे प्रकार के लिए पूछना पसंद करता हूं क्योंकि बाकी सभी कोड में decreasing = TRUEनोटिफ़िकेशन की तुलना में इरादा प्राप्त करना कहीं अधिक आसान है -
गविन सिम्पसन

2
@GavinSimpson; मुझे लगता है कि इस हिस्से के बारे levels(theTable$Position) <- c(...)में अवांछित व्यवहार की ओर जाता है जहां डेटा फ्रेम की वास्तविक प्रविष्टियां फिर से व्यवस्थित हो जाती हैं, न कि केवल कारक के स्तर। इस प्रश्न को देखें । शायद आपको उन पंक्तियों को संशोधित या हटाना चाहिए?
एंटोन

2
एंटोन के साथ दृढ़ता से सहमत हैं। मैंने सिर्फ इस सवाल को देखा और इधर-उधर ताक-झांक करता रहा, जहां उन्हें इस्तेमाल करने की बुरी सलाह मिली levels<-। मैं उस हिस्से को संपादित करने जा रहा हूं, कम से कम अस्थायी रूप से।
ग्रेगर थॉमस

2
सुझाव के लिए @Anton धन्यवाद (और संपादन के लिए ग्रेगर के लिए); मैं levels<-()आज के माध्यम से ऐसा कभी नहीं करूंगा । यह 8 साल पहले से कुछ है और मैं याद नहीं कर सकता कि अगर चीजें अलग थीं या फिर मैं सिर्फ सादा गलत था, लेकिन इसकी परवाह किए बिना, यह गलत है और इसे मिटा दिया जाना चाहिए! धन्यवाद!
गैविन सिम्पसन

220

@GavinSimpson: इसके reorderलिए एक शक्तिशाली और प्रभावी उपाय है:

ggplot(theTable,
       aes(x=reorder(Position,Position,
                     function(x)-length(x)))) +
       geom_bar()

7
वास्तव में +1 और विशेष रूप से इस मामले में जहां एक तार्किक आदेश है कि हम संख्यात्मक रूप से शोषण कर सकते हैं। यदि हम श्रेणियों के मनमाने ढंग से आदेश देने पर विचार करते हैं और हम वर्णानुक्रम नहीं चाहते हैं तो सीधे दिखाए गए स्तरों को निर्दिष्ट करना आसान (आसान) है।
गैविन सिम्पसन

2
यह सबसे साफ है। मूल
डेटाफ़्रेम

लवली, सिर्फ इस बात पर ध्यान दिया जाता है कि आप इसे कुछ ज्यादा ही सक्सेसफुल तरीके से कर सकते हैं, अगर आप चाहते हैं कि आप लम्बे फंक्शन द्वारा ऑर्डर करें और आरोही ऑर्डर ठीक है, तो कुछ ऐसा है जो मैं अक्सर करना चाहता हूँ:ggplot(theTable,aes(x=reorder(Position,Position,length))+geom_bar()
पोस्टलैम

146

scale_x_discrete (limits = ...)सलाखों के क्रम को निर्दिष्ट करने के लिए उपयोग करना ।

positions <- c("Goalkeeper", "Defense", "Striker")
p <- ggplot(theTable, aes(x = Position)) + scale_x_discrete(limits = positions)

12
आपका समाधान मेरी स्थिति के लिए सबसे उपयुक्त है, क्योंकि मैं x के साथ प्लॉट करने के लिए प्रोग्राम करना चाहता हूं एक डेटा स्तंभ में चर द्वारा व्यक्त किया गया एक मनमाना कॉलम है। चर को शामिल करने वाले एक्सप्रेशन की व्यवस्था को अभिव्यक्त करने के लिए अन्य सुझाव कठिन होंगे। धन्यवाद! यदि रुचि है, तो मैं आपके सुझाव का उपयोग करके अपना समाधान साझा कर सकता हूं। बस एक और मुद्दा, स्केल_एक्स_डिस्क्रीट (सीमा = ...) को जोड़ते हुए, मैंने पाया कि चार्ट के दाईं ओर बार-चार्ट जितना खाली स्थान है। मैं रिक्त स्थान से कैसे छुटकारा पा सकता हूं? जैसे कि यह किसी उद्देश्य की पूर्ति नहीं करता है।
यू शेन

हिस्टोग्राम सलाखों के आदेश के लिए यह आवश्यक लगता है
जियोथेक्टरी

9
QIBIN: वाह ... यहाँ अन्य उत्तर काम करते हैं, लेकिन अब तक आपका जवाब न केवल सबसे संक्षिप्त और सुरुचिपूर्ण है, बल्कि ggplot के ढांचे के भीतर से सोचने पर सबसे स्पष्ट है। धन्यवाद।
दान गुयेन

जब मैंने अपने डेटा पर इस समाधान की कोशिश की, तो यह एनए ग्राफ नहीं था। क्या इस समाधान का उपयोग करने का कोई तरीका है और क्या यह NA का ग्राफ़ है?
user2460499

यह एक सुंदर और सरल उपाय है - धन्यवाद !!
कालिफ़ वॉन

91

मुझे लगता है कि पहले से ही उपलब्ध समाधान अत्यधिक क्रिया हैं। Ggplot के साथ एक आवृत्ति सॉर्टेड बारप्लॉट करने के लिए एक अधिक संक्षिप्त तरीका है

ggplot(theTable, aes(x=reorder(Position, -table(Position)[Position]))) + geom_bar()

यह एलेक्स ब्राउन द्वारा सुझाए गए के समान है, लेकिन थोड़ा छोटा है और बिना किसी फ़ंक्शन के परिभाषा के काम करता है।

अपडेट करें

मुझे लगता है कि मेरा पुराना समाधान उस समय अच्छा था, लेकिन आजकल मैं उपयोग करूंगा forcats::fct_infreqजो आवृत्ति द्वारा कारक स्तरों को छांट रहा है:

require(forcats)

ggplot(theTable, aes(fct_infreq(Position))) + geom_bar()

मुझे फंक्शन रीक्रिएट करने का दूसरा तर्क समझ में नहीं आता है और यह क्या करता है। क्या आप कृपया बता सकते हैं कि क्या हो रहा है?
user3282777

1
@ user3282777 आपने डॉक्स स्टेट की कोशिश की है ।eth.chz.ch/R-manual/R-devel/library/stats/html/… ?
होल्गर ब्रैंडल सेप

1
महान समाधान! दूसरों को साफ-सुथरा समाधान देते हुए देखना अच्छा है!
माइक

29

जैसा reorder()एलेक्स ब्राउन के जवाब में, हम भी इस्तेमाल कर सकते हैं forcats::fct_reorder()। यह मूल रूप से 1 arg में निर्दिष्ट कारकों को क्रमबद्ध करेगा, एक निर्दिष्ट फ़ंक्शन (डिफ़ॉल्ट = माध्यिका, जिसे हम यहां उपयोग करते हैं, जैसे कि प्रति कारक एक मान स्तर) के बाद 2 arg में मानों के अनुसार।

यह शर्म की बात है कि ओपी के प्रश्न में, आवश्यक आदेश भी वर्णानुक्रमिक है क्योंकि जब आप कारक बनाते हैं तो यह डिफ़ॉल्ट क्रम होता है, इसलिए यह छिपाएगा कि यह फ़ंक्शन वास्तव में क्या कर रहा है। इसे और अधिक स्पष्ट करने के लिए, मैं "गोलकीपर" को "Zoalkeeper" से बदल दूंगा।

library(tidyverse)
library(forcats)

theTable <- data.frame(
                Name = c('James', 'Frank', 'Jean', 'Steve', 'John', 'Tim'),
                Position = c('Zoalkeeper', 'Zoalkeeper', 'Defense',
                             'Defense', 'Defense', 'Striker'))

theTable %>%
    count(Position) %>%
    mutate(Position = fct_reorder(Position, n, .desc = TRUE)) %>%
    ggplot(aes(x = Position, y = n)) + geom_bar(stat = 'identity')

यहां छवि विवरण दर्ज करें


1
IMHO सबसे अच्छा समाधान forcats के रूप में के रूप में अच्छी तरह से एक tidyverse पैकेज dplyr है।
c0bra

Zoalkeeper के लिए अंगूठे
otwtm

23

कारकों की एक सरल डापर आधारित पुनरावृत्ति इस समस्या को हल कर सकती है:

library(dplyr)

#reorder the table and reset the factor to that ordering
theTable %>%
  group_by(Position) %>%                              # calculate the counts
  summarize(counts = n()) %>%
  arrange(-counts) %>%                                # sort by counts
  mutate(Position = factor(Position, Position)) %>%   # reset factor
  ggplot(aes(x=Position, y=counts)) +                 # plot 
    geom_bar(stat="identity")                         # plot histogram

19

आपको केवल Positionएक निर्दिष्ट कारक होने के लिए कॉलम को निर्दिष्ट करने की आवश्यकता है जहां स्तरों को उनकी गणना द्वारा आदेश दिया गया है:

theTable <- transform( theTable,
       Position = ordered(Position, levels = names( sort(-table(Position)))))

(ध्यान दें कि कॉलम table(Position)की एक आवृत्ति-गणना पैदा करता है Position।)

फिर आपका ggplotकार्य गणना के घटते क्रम में सलाखों को दिखाएगा। मैं नहीं जानता कि क्या कोई विकल्प geom_barस्पष्ट रूप से एक आदेशित कारक बनाने के बिना ऐसा करने का विकल्प है ।


मैंने आपके कोड को वहां पूरी तरह से पार्स नहीं किया, लेकिन मुझे यकीन है कि reorder()सांख्यिकी पुस्तकालय से समान कार्य पूरा होता है।
पीछा

@ देखें कि आप reorder()इस मामले में कैसे प्रयोग करते हैं ? रिडरिंग की आवश्यकता वाले कारक को स्वयं के कुछ फ़ंक्शन द्वारा फिर से व्यवस्थित करने की आवश्यकता है और मैं ऐसा करने के लिए एक अच्छा तरीका देखने के लिए संघर्ष कर रहा हूं।
गैविन सिम्पसन

ठीक है, with(theTable, reorder(Position, as.character(Position), function(x) sum(duplicated(x))))एक ही रास्ता है, और एक और with(theTable, reorder(Position, as.character(Position), function(x) as.numeric(table(x))))लेकिन ये बस के रूप में सजाया जाता है ...
गेविन सिम्पसन

मैंने उत्तर का उपयोग करने के sortबजाय थोड़ा सा सरलीकृत कियाorder
प्रसाद चलसानी

@ गेविन - शायद मैंने प्रसाद के मूल कोड को गलत समझा (मुझे परीक्षण करने के लिए इस मशीन पर आर नहीं है ...) लेकिन ऐसा लग रहा था जैसे वह आवृत्ति के आधार पर श्रेणियों को फिर से व्यवस्थित reorderकर रहा है , जो करने में माहिर है। मैं इस सवाल के लिए सहमत हूं कि कुछ और चीजों की आवश्यकता है। गलतफहमी के लिए खेद है।
चेस

17

@HolgerBrandl द्वारा उल्लिखित forcats :: fct_infreq के अलावा, forcats :: fct_rev है, जो कारक क्रम को उलट देता है।

theTable <- data.frame(
    Position= 
        c("Zoalkeeper", "Zoalkeeper", "Defense",
          "Defense", "Defense", "Striker"),
    Name=c("James", "Frank","Jean",
           "Steve","John", "Tim"))

p1 <- ggplot(theTable, aes(x = Position)) + geom_bar()
p2 <- ggplot(theTable, aes(x = fct_infreq(Position))) + geom_bar()
p3 <- ggplot(theTable, aes(x = fct_rev(fct_infreq(Position)))) + geom_bar()

gridExtra::grid.arrange(p1, p2, p3, nrow=3)             

gplot आउटपुट


"fct_infreq (स्थिति)" छोटी चीज है जो इतना कुछ करती है, धन्यवाद !!
पॉल

12

मैं zach से सहमत हूं कि dplyr के भीतर गिनती करना सबसे अच्छा समाधान है। मैंने इसे सबसे छोटा संस्करण पाया है:

dplyr::count(theTable, Position) %>%
          arrange(-n) %>%
          mutate(Position = factor(Position, Position)) %>%
          ggplot(aes(x=Position, y=n)) + geom_bar(stat="identity")

यह भी पहले से ही कारक स्तरों को फिर से व्यवस्थित करने की तुलना में काफी तेज होगा क्योंकि गिनती को डीजीपीएल में नहीं किया जाता है या उपयोग नहीं किया जाता है table


12

यदि चार्ट कॉलम एक संख्यात्मक चर के रूप में नीचे दिए गए डेटाफ्रेम में आते हैं, तो आप एक सरल समाधान का उपयोग कर सकते हैं:

ggplot(df, aes(x = reorder(Colors, -Qty, sum), y = Qty)) 
+ geom_bar(stat = "identity")  

सॉर्ट चर (-Qty) से पहले ऋण चिह्न सॉर्ट दिशा (आरोही / अवरोही) को नियंत्रित करता है

यहाँ परीक्षण के लिए कुछ डेटा है:

df <- data.frame(Colors = c("Green","Yellow","Blue","Red","Yellow","Blue"),  
                 Qty = c(7,4,5,1,3,6)
                )

**Sample data:**
  Colors Qty
1  Green   7
2 Yellow   4
3   Blue   5
4    Red   1
5 Yellow   3
6   Blue   6

जब मुझे यह धागा मिला, तो वह उत्तर था जिसकी मुझे तलाश थी। आशा है कि यह दूसरों के लिए उपयोगी है।


8

एक कारक के स्तरों को क्रम में करने के लिए रीऑर्डर का उपयोग करते हुए एक और विकल्प । गिनती के आधार पर आरोही (n) या अवरोही क्रम (-n) में। पैकेज fct_reorderसे उपयोग करने वाले के समान forcats:

घटते क्रम में

df %>%
  count(Position) %>%
  ggplot(aes(x = reorder(Position, -n), y = n)) +
  geom_bar(stat = 'identity') +
  xlab("Position")

यहां छवि विवरण दर्ज करें

आरोही क्रम

df %>%
  count(Position) %>%
  ggplot(aes(x = reorder(Position, n), y = n)) +
  geom_bar(stat = 'identity') +
  xlab("Position")

यहां छवि विवरण दर्ज करें

डेटा ढांचा:

df <- structure(list(Position = structure(c(3L, 3L, 1L, 1L, 1L, 2L), .Label = c("Defense", 
"Striker", "Zoalkeeper"), class = "factor"), Name = structure(c(2L, 
1L, 3L, 5L, 4L, 6L), .Label = c("Frank", "James", "Jean", "John", 
"Steve", "Tim"), class = "factor")), class = "data.frame", row.names = c(NA, 
-6L))

5

चूंकि हम केवल एक चर ("स्थिति") के वितरण को दो चर के बीच संबंध को देखने के रूप में देख रहे हैं , तो शायद एक हिस्टोग्राम अधिक उपयुक्त ग्राफ होगा। ggplot में geom_histogram () है जो इसे आसान बनाता है:

ggplot(theTable, aes(x = Position)) + geom_histogram(stat="count")

यहां छवि विवरण दर्ज करें

Geom_histogram () का उपयोग करना:

मुझे लगता है कि geom_histogram ( ) थोड़ा विचित्र है क्योंकि यह निरंतर और असतत डेटा का अलग-अलग व्यवहार करता है।

के लिए निरंतर डेटा , तुम बस का उपयोग कर सकते geom_histogram () कोई पैरामीटर के साथ। उदाहरण के लिए, यदि हम एक संख्यात्मक वेक्टर "स्कोर" में जोड़ते हैं ...

    Name   Position   Score  
1   James  Goalkeeper 10
2   Frank  Goalkeeper 20
3   Jean   Defense    10
4   Steve  Defense    10
5   John   Defense    20
6   Tim    Striker    50

और "स्कोर" चर पर geom_histogram () का उपयोग करें ...

ggplot(theTable, aes(x = Score)) + geom_histogram()

यहां छवि विवरण दर्ज करें

के लिए असतत डेटा "स्थिति" की तरह हम प्रयोग कर सलाखों की ऊंचाई के लिए y मूल्य देने के लिए सौंदर्य की गणना एक गणना आंकड़ा बारे में बताने की stat = "count":

 ggplot(theTable, aes(x = Position)) + geom_histogram(stat = "count")

नोट: उत्सुकता से और भ्रमित रूप से आप stat = "count"निरंतर डेटा के लिए भी उपयोग कर सकते हैं और मुझे लगता है कि यह अधिक सौंदर्यवादी रूप से मनभावन ग्राफ प्रदान करता है।

ggplot(theTable, aes(x = Score)) + geom_histogram(stat = "count")

यहां छवि विवरण दर्ज करें

संपादन : देबंजन के सहायक सुझावों के जवाब में विस्तारित उत्तर ।


0

मुझे यह बहुत कष्टप्रद लगा कि ggplot2इसके लिए कोई 'स्वचालित' समाधान पेश नहीं किया गया। इसीलिए मैंने bar_chart()फंक्शन को बनाया ggcharts

ggcharts::bar_chart(theTable, Position)

यहां छवि विवरण दर्ज करें

डिफ़ॉल्ट bar_chart()रूप से सलाखों को सॉर्ट करता है और एक क्षैतिज भूखंड प्रदर्शित करता है। उस सेट को बदलने के लिए horizontal = FALSE। इसके अलावा, bar_chart()बार और अक्ष के बीच भद्दा 'अंतर' को हटाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.