Ggplot2 के साथ साइड-बाय-साइड प्लॉट्स


339

मैं ggplot2 पैकेज का उपयोग करके दो प्लॉटों को एक साथ रखना चाहता हूं , अर्थात इसके बराबर par(mfrow=c(1,2))

उदाहरण के लिए, मैं निम्नलिखित दो भूखंडों को एक ही पैमाने के साथ-साथ दिखाना चाहूंगा।

x <- rnorm(100)
eps <- rnorm(100,0,.2)
qplot(x,3*x+eps)
qplot(x,2*x+eps)

क्या मुझे उन्हें एक ही data.frame में डालने की आवश्यकता है?

qplot(displ, hwy, data=mpg, facets = . ~ year) + geom_smooth()

मुझे लगता है कि आप जाली के साथ ऐसा करने में सक्षम हो सकते हैं। क्या ggplot2 एक कठिन आवश्यकता है?
जेडी लॉन्ग

8
नहीं, लेकिन मैंने पहले ही समय में क्यूप्लॉट्स को जोड़ दिया था इसलिए यह मुझे पसंद आया। :-) और मैं ggplot के साथ खेलने की कोशिश कर रहा हूँ।
क्रिस्टोफर डुबोइस

1
बाहर की जाँच करें stackoverflow.com/questions/31798162/…
Boern

1
एक अच्छे अवलोकन के लिए, अंडे के पैकेज के लिए विगनेट देखें : एक पृष्ठ पर कई भूखंडों को बिछाते हुए
हेनरिक

जवाबों:


505

अगल-बगल कोई भी ggplots (या ग्रिड पर n प्लॉट)

पैकेज grid.arrange()में फ़ंक्शन gridExtraकई भूखंडों को संयोजित करेगा; यह है कि आप कैसे दो पक्ष की ओर से डालते हैं।

require(gridExtra)
plot1 <- qplot(1)
plot2 <- qplot(1)
grid.arrange(plot1, plot2, ncol=2)

यह उपयोगी है जब दो भूखंड एक ही डेटा पर आधारित नहीं होते हैं, उदाहरण के लिए यदि आप बिना फेरबदल () का उपयोग किए बिना विभिन्न चर को साजिश करना चाहते हैं।

यह आउटपुट को साइड इफेक्ट के रूप में प्लॉट करेगा। एक फाइल करने के लिए पक्ष प्रभाव को मुद्रित करने के (जैसे एक डिवाइस ड्राइवर को निर्दिष्ट pdf, png, आदि), उदाहरण के लिए

pdf("foo.pdf")
grid.arrange(plot1, plot2)
dev.off()

या, के arrangeGrob()साथ संयोजन में उपयोग करें ggsave(),

ggsave("foo.pdf", arrangeGrob(plot1, plot2))

यह दो अलग-अलग प्लॉट बनाने के बराबर है par(mfrow = c(1,2))। यह न केवल डेटा की व्यवस्था करने के लिए समय बचाता है, यह आवश्यक है जब आप दो भिन्न प्लॉट चाहते हैं।


परिशिष्ट: पहलुओं का उपयोग करना

विभिन्न समूहों के लिए समान भूखंड बनाने के लिए पहलू सहायक होते हैं। यह नीचे कई उत्तरों में नीचे इंगित किया गया है, लेकिन मैं इस दृष्टिकोण को उपरोक्त भूखंडों के बराबर उदाहरणों के साथ उजागर करना चाहता हूं।

mydata <- data.frame(myGroup = c('a', 'b'), myX = c(1,1))

qplot(data = mydata, 
    x = myX, 
    facets = ~myGroup)

ggplot(data = mydata) + 
    geom_bar(aes(myX)) + 
    facet_wrap(~myGroup)

अपडेट करें

में plot_gridसमारोह के लिए cowplotएक विकल्प के रूप में बाहर की जाँच के लायक है grid.arrange। नीचे दिए गए @ क्लॉस-विल्के द्वारा उत्तर देखें और एक समतुल्य दृष्टिकोण के लिए यह विगनेट ; लेकिन फ़ंक्शन इस विगनेट के आधार पर प्लॉट लोकेशन और आकार पर महीन नियंत्रण की अनुमति देता है ।


2
जब मैंने ggplot ऑब्जेक्ट का उपयोग करके आपका कोड चलाया, तो sidebysideplot शून्य है। यदि आप आउटपुट को किसी फ़ाइल में सहेजना चाहते हैं, तो gridArrange का उपयोग करें। देखें stackoverflow.com/questions/17059099/…
जिम

@ जोम आपको इस ओर इशारा करने के लिए धन्यवाद देता है। मैंने अपने उत्तर को संशोधित कर दिया है। अगर कोई सवाल रह गया हो तो मुझे बताएं।
डेविड लेबॉयर

1
क्या ग्रिड.रैंग अब समाप्त हो गया है?
Atticus29

?grid.arrangeमुझे लगता है कि इस समारोह को अब अरेंजग्रोब कहा जाता है। मैं वही कर पा रहा था जो मुझे करना था a <- arrangeGrob(p1, p2)और फिर मैं चाहता था print(a)
ब्लेकॉफ्ट

@blakeoft क्या आपने उदाहरणों को देखा? grid.arrangeअभी भी एक वैध, गैर-वंचित कार्य है। क्या आपने फ़ंक्शन का उपयोग करने की कोशिश की? क्या होता है, यदि आप अपेक्षा नहीं करते हैं।
डेविड लेबॉयर

159

आधारित समाधानों में से एक यह grid.arrangeहै कि वे पत्र (ए, बी, आदि) के साथ भूखंडों को लेबल करना मुश्किल बनाते हैं, क्योंकि अधिकांश पत्रिकाओं की आवश्यकता होती है।

मैंने इसे (और कुछ अन्य) मुद्दों को हल करने के लिए काउप्लॉट पैकेज लिखा , विशेष रूप से फ़ंक्शन plot_grid():

library(cowplot)

iris1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) +
  geom_boxplot() + theme_bw()

iris2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
  geom_density(alpha = 0.7) + theme_bw() +
  theme(legend.position = c(0.8, 0.8))

plot_grid(iris1, iris2, labels = "AUTO")

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

जो वस्तु plot_grid()लौटाता है वह दूसरी ggplot2 वस्तु है, और आप इसे ggsave()हमेशा की तरह बचा सकते हैं :

p <- plot_grid(iris1, iris2, labels = "AUTO")
ggsave("plot.pdf", p)

वैकल्पिक रूप से, आप काउप्लॉट फ़ंक्शन का उपयोग कर सकते हैं save_plot(), जो चारों ओर एक पतला आवरण है ggsave()जो संयुक्त भूखंडों के लिए सही आयाम प्राप्त करना आसान बनाता है, जैसे:

p <- plot_grid(iris1, iris2, labels = "AUTO")
save_plot("plot.pdf", p, ncol = 2)

( ncol = 2तर्क बताता है save_plot()कि अगल-बगल दो प्लॉट हैं, और save_plot()सहेजी गई छवि को दो बार चौड़ा करता है।)

ग्रिड में भूखंडों को व्यवस्थित करने के तरीके के अधिक गहराई से वर्णन के लिए इस विगनेट को देखें एक साझा किंवदंती के साथ प्लॉट बनाने का तरीका समझाने वाला एक विगनेट भी है

भ्रम की एक लगातार बात यह है कि काउप्लॉट पैकेज डिफ़ॉल्ट ggplot2 थीम को बदलता है। पैकेज उस तरह से व्यवहार करता है क्योंकि यह मूल रूप से आंतरिक प्रयोगशाला उपयोगों के लिए लिखा गया था, और हम कभी भी डिफ़ॉल्ट विषय का उपयोग नहीं करते हैं। यदि यह समस्या का कारण बनता है, तो आप उनके आसपास काम करने के लिए निम्नलिखित तीन दृष्टिकोणों में से एक का उपयोग कर सकते हैं:

1. हर प्लॉट के लिए मैन्युअल रूप से थीम सेट करें। मुझे लगता है कि प्रत्येक प्लॉट के लिए किसी विशेष विषय को निर्दिष्ट करना हमेशा अच्छा होता है, जैसे मैंने + theme_bw()ऊपर दिए उदाहरण में किया था । यदि आप किसी विशेष विषय को निर्दिष्ट करते हैं, तो डिफ़ॉल्ट विषय कोई मायने नहीं रखता है।

2. डिफ़ॉल्ट थीम को वापस ggplot2 डिफ़ॉल्ट पर वापस लाएं। आप इसे कोड की एक पंक्ति के साथ कर सकते हैं:

theme_set(theme_gray())

3. पैकेज संलग्न किए बिना काउलपॉट फ़ंक्शन को कॉल करें। आप कॉल नहीं कर सकते हैं library(cowplot)या require(cowplot)इसके बजाय प्रीप्ल्ड करके काउप्लॉट फ़ंक्शन को कॉल कर सकते हैं cowplot::। उदाहरण के लिए, ggplot2 डिफ़ॉल्ट थीम का उपयोग करने वाला उपरोक्त उदाहरण बन जाएगा:

## Commented out, we don't call this
# library(cowplot)

iris1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) +
  geom_boxplot()

iris2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
  geom_density(alpha = 0.7) +
  theme(legend.position = c(0.8, 0.8))

cowplot::plot_grid(iris1, iris2, labels = "AUTO")

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

अपडेट:

  • कोप्लॉट 1.0 के रूप में, डिफ़ॉल्ट ggplot2 थीम को अब नहीं बदला गया है।
  • Ggplot2 3.0.0 के रूप में, प्लॉट को सीधे लेबल किया जा सकता है, उदाहरण के लिए यहां देखें

उत्पादन में cowplot दोनों भूखंडों की पृष्ठभूमि विषय को हटा रहा है? क्या कोई विकल्प है?
VAR121

@ VAR121 हां, यह कोड की एक पंक्ति है। परिचयात्मक विगनेट
क्लॉस

क्या इस पैकेज के साथ सभी प्लॉटों के लिए समान y पैमाना संभव है?
हरमन टूथ्रोट

आपको मिलान करने के लिए y तराजू को मैन्युअल रूप से सेट करना होगा। या पहलू पर विचार करें।
क्लॉस विलके

आप ग्रिड का उपयोग करने से पहले प्रत्येक प्लॉट के लिए एक ggtitle () सेट कर सकते हैं।
सीनोसैपियन

49

आप विंस्टन चांग के आर कुकबुकmultiplot से निम्न फ़ंक्शन का उपयोग कर सकते हैं

multiplot(plot1, plot2, cols=2)

multiplot <- function(..., plotlist=NULL, cols) {
    require(grid)

    # Make a list from the ... arguments and plotlist
    plots <- c(list(...), plotlist)

    numPlots = length(plots)

    # Make the panel
    plotCols = cols                          # Number of columns of plots
    plotRows = ceiling(numPlots/plotCols) # Number of rows needed, calculated from # of cols

    # Set up the page
    grid.newpage()
    pushViewport(viewport(layout = grid.layout(plotRows, plotCols)))
    vplayout <- function(x, y)
        viewport(layout.pos.row = x, layout.pos.col = y)

    # Make each plot, in the correct location
    for (i in 1:numPlots) {
        curRow = ceiling(i/plotCols)
        curCol = (i-1) %% plotCols + 1
        print(plots[[i]], vp = vplayout(curRow, curCol ))
    }

}

24

पैचवर्क पैकेज का उपयोग करके , आप बस +ऑपरेटर का उपयोग कर सकते हैं :

library(ggplot2)
library(patchwork)

p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp))
p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))


p1 + p2

घपला


पूर्णता के लिए, पैचवर्क अब CRAN पर भी है। आशा है कि आप मेरे छोटे से संपादन से खुश होंगे
Tjebo

18

हां, मेथिंक आपको अपने डेटा को उचित रूप से व्यवस्थित करने की आवश्यकता है। एक तरीका यह होगा:

X <- data.frame(x=rep(x,2),
                y=c(3*x+eps, 2*x+eps),
                case=rep(c("first","second"), each=100))

qplot(x, y, data=X, facets = . ~ case) + geom_smooth()

मुझे यकीन है कि प्लायर या रिशेप में बेहतर चालें हैं - मैं अभी भी हैडली द्वारा इन सभी शक्तिशाली पैकेजों पर गति करने के लिए नहीं हूं।


16

रिशेप पैकेज का उपयोग करके आप ऐसा कुछ कर सकते हैं।

library(ggplot2)
wide <- data.frame(x = rnorm(100), eps = rnorm(100, 0, .2))
wide$first <- with(wide, 3 * x + eps)
wide$second <- with(wide, 2 * x + eps)
long <- melt(wide, id.vars = c("x", "eps"))
ggplot(long, aes(x = x, y = value)) + geom_smooth() + geom_point() + facet_grid(.~ variable)

12

इसमें मल्टीफंक्शनल पैकेज भी है जो उल्लेख के लायक है। इसका जवाब भी देखिए ।

library(ggplot2)
theme_set(theme_bw())

q1 <- ggplot(mtcars) + geom_point(aes(mpg, disp))
q2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))
q3 <- ggplot(mtcars) + geom_smooth(aes(disp, qsec))
q4 <- ggplot(mtcars) + geom_bar(aes(carb))

library(magrittr)
library(multipanelfigure)
figure1 <- multi_panel_figure(columns = 2, rows = 2, panel_label_type = "none")
# show the layout
figure1

figure1 %<>%
  fill_panel(q1, column = 1, row = 1) %<>%
  fill_panel(q2, column = 2, row = 1) %<>%
  fill_panel(q3, column = 1, row = 2) %<>%
  fill_panel(q4, column = 2, row = 2)
figure1

# complex layout
figure2 <- multi_panel_figure(columns = 3, rows = 3, panel_label_type = "upper-roman")
figure2

figure2 %<>%
  fill_panel(q1, column = 1:2, row = 1) %<>%
  fill_panel(q2, column = 3, row = 1) %<>%
  fill_panel(q3, column = 1, row = 2) %<>%
  fill_panel(q4, column = 2:3, row = 2:3)
figure2

2018-07-06 को रेप्रेक्स पैकेज (v0.2.0.9000) द्वारा बनाया गया ।


9

ggplot2 ग्रिड ग्राफिक्स पर आधारित है, जो एक पृष्ठ पर भूखंडों की व्यवस्था के लिए एक अलग प्रणाली प्रदान करता है। par(mfrow...)के रूप में ग्रिड वस्तुओं (बुलाया आदेश, एक प्रत्यक्ष समतुल्य नहीं है grobs ) जरूरी तुरंत तैयार नहीं हैं, लेकिन संग्रहीत और नियमित रूप से आर वस्तुओं के रूप में हेरफेर किया जा सकता एक ग्राफिकल उत्पादन के लिए परिवर्तित किया जा रहा से पहले। यह आधार ग्राफिक्स के इस अब के मॉडल की तुलना में अधिक लचीलेपन को सक्षम बनाता है , लेकिन रणनीति जरूरी थोड़ा अलग है।

मैंने grid.arrange()यथासंभव सरल इंटरफ़ेस प्रदान करने के लिए लिखा था par(mfrow)। अपने सरलतम रूप में, कोड इस तरह दिखेगा:

library(ggplot2)
x <- rnorm(100)
eps <- rnorm(100,0,.2)
p1 <- qplot(x,3*x+eps)
p2 <- qplot(x,2*x+eps)

library(gridExtra)
grid.arrange(p1, p2, ncol = 2)

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

इस विगनेट में अधिक विकल्प विस्तृत हैं ।

एक आम शिकायत यह है कि भूखंडों को आवश्यक रूप से संरेखित नहीं किया जाता है जैसे कि उनके पास विभिन्न आकार के अक्ष लेबल होते हैं, लेकिन यह डिज़ाइन द्वारा है: grid.arrangeविशेष-केस ggplot2 ऑब्जेक्ट्स के लिए कोई प्रयास नहीं करता है, और उदाहरण के लिए अन्य ग्रब्स (जाली प्लॉट्स) के साथ समान रूप से व्यवहार करता है )। यह केवल आयताकार लेआउट में खांचे रखता है।

Ggplot2 ऑब्जेक्ट्स के विशेष मामले के लिए, मैंने एक अन्य फ़ंक्शन लिखा ggarrange, एक समान इंटरफ़ेस के साथ, जो प्लॉट पैनल (चेहरे के प्लॉट सहित) को संरेखित करने का प्रयास करता है और उपयोगकर्ता द्वारा परिभाषित किए गए पहलू अनुपात का सम्मान करने की कोशिश करता है।

library(egg)
ggarrange(p1, p2, ncol = 2)

दोनों कार्य संगत हैं ggsave()। विभिन्न विकल्पों के सामान्य अवलोकन और कुछ ऐतिहासिक संदर्भों के लिए, यह विगनेट अतिरिक्त जानकारी प्रदान करता है


9

अद्यतन: यह उत्तर बहुत पुराना है। gridExtra::grid.arrange()अब अनुशंसित दृष्टिकोण है। अगर यह उपयोगी हो सकता है तो मैं इसे यहाँ छोड़ देता हूँ।


स्टीफन टर्नर पोस्ट arrange()पर समारोह जेनेटिक्स करवाने ब्लॉग (आवेदन निर्देश के लिए पोस्ट देखें)

vp.layout <- function(x, y) viewport(layout.pos.row=x, layout.pos.col=y)
arrange <- function(..., nrow=NULL, ncol=NULL, as.table=FALSE) {
 dots <- list(...)
 n <- length(dots)
 if(is.null(nrow) & is.null(ncol)) { nrow = floor(n/2) ; ncol = ceiling(n/nrow)}
 if(is.null(nrow)) { nrow = ceiling(n/ncol)}
 if(is.null(ncol)) { ncol = ceiling(n/nrow)}
        ## NOTE see n2mfrow in grDevices for possible alternative
grid.newpage()
pushViewport(viewport(layout=grid.layout(nrow,ncol) ) )
 ii.p <- 1
 for(ii.row in seq(1, nrow)){
 ii.table.row <- ii.row 
 if(as.table) {ii.table.row <- nrow - ii.table.row + 1}
  for(ii.col in seq(1, ncol)){
   ii.table <- ii.p
   if(ii.p > n) break
   print(dots[[ii.table]], vp=vp.layout(ii.table.row, ii.col))
   ii.p <- ii.p + 1
  }
 }
}

9
यह मूल रूप से एक बहुत पुराना संस्करण है grid.arrange(काश मैंने उस समय मेलिंग सूचियों में इसे पोस्ट नहीं किया होता - इन ऑनलाइन संसाधनों को अपडेट करने का कोई तरीका नहीं है), पैकेज्ड संस्करण एक बेहतर विकल्प है यदि आप मुझसे पूछें
बैपटिस्ट

4

का उपयोग कर tidyverse:

x <- rnorm(100)
eps <- rnorm(100,0,.2)
df <- data.frame(x, eps) %>% 
  mutate(p1 = 3*x+eps, p2 = 2*x+eps) %>% 
  tidyr::gather("plot", "value", 3:4) %>% 
  ggplot(aes(x = x , y = value)) + 
    geom_point() + 
    geom_smooth() + 
    facet_wrap(~plot, ncol =2)

df

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


1

उपरोक्त समाधान कुशल नहीं हो सकता है यदि आप एक लूप का उपयोग करके कई ggplot प्लॉट्स को प्लॉट करना चाहते हैं (जैसे कि यहाँ पूछा गया: अलग-अलग Y- अक्ष मानों के साथ एक लूप का उपयोग करके ggplot में कई प्लॉट बनाना ), जो अज्ञात का विश्लेषण करने में एक वांछित कदम है ( या बड़े) डेटा-सेट (उदाहरण के लिए, जब आप किसी डेटा-सेट में सभी चर की गणना करना चाहते हैं)।

नीचे दिए गए कोड से पता चलता है कि 'मल्टीप्लोट ()' के ऊपर बताए गए तरीके का उपयोग कैसे किया जाए, जिसका स्रोत यहां है: http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplotot2 :

plotAllCounts <- function (dt){   
  plots <- list();
  for(i in 1:ncol(dt)) {
    strX = names(dt)[i]
    print(sprintf("%i: strX = %s", i, strX))
    plots[[i]] <- ggplot(dt) + xlab(strX) +
      geom_point(aes_string(strX),stat="count")
  }

  columnsToPlot <- floor(sqrt(ncol(dt)))
  multiplot(plotlist = plots, cols = columnsToPlot)
}

अब फ़ंक्शन को चलाएं - एक पृष्ठ पर ggplot का उपयोग करके मुद्रित किए गए सभी चर के लिए मायने रखता है

dt = ggplot2::diamonds
plotAllCounts(dt)

ध्यान देने वाली एक बात यह है कि:
उपयोग करना aes(get(strX)), जिसे आप सामान्य रूप से लूप में उपयोग करते हैं ggplot, इसके बजाय उपरोक्त कोड aes_string(strX)में वांछित भूखंडों को आकर्षित नहीं करेंगे। इसके बजाय, यह कई बार आखिरी साजिश करेगा। मुझे पता नहीं क्यों - यह करना पड़ सकता है aesऔर aes_stringमें कहा जाता है ggplot

अन्यथा, आशा है कि आप फ़ंक्शन को उपयोगी पाएंगे।


1
ध्यान दें कि आपका कोड उन plotsवस्तुओं को बढ़ाता है for-loopजिनके भीतर अत्यधिक अक्षमता है और इसमें अनुशंसित नहीं है R। कृपया इसे करने के लिए बेहतर तरीके जानने के लिए इन महान पदों को देखें: आर में कुशल संचय , डेटा फ्रेम की पंक्तियों पर एक फ़ंक्शन को लागू करना और आर-ओरिएंटेड वर्कफ़्लोज़ के साथ आर में tidyverse
तुंग

चर के माध्यम से लूप करने के लिए अधिक कुशल तरीका tidy evaluationदृष्टिकोण का उपयोग करना है जो कि ggplot2 v.3.0.0 stackoverflow.com/a/52045613/786542 के
Tung

0

मेरे अनुभव में ग्रिडएक्स्ट्रा: ग्रिड.आर्गेन पूरी तरह से काम करता है, यदि आप एक लूप में प्लॉट उत्पन्न करने की कोशिश कर रहे हैं।

लघु कोड स्निपेट:

gridExtra::grid.arrange(plot1, plot2, ncol = 2)

बपतिस्मा देने वाले के उत्तर 2: 17 के 4:20 पर आपका उत्तर कैसे सुधरता है? आपका उत्तर डुप्लिकेट लगता है। यहां देखें कि क्या स्वीकार्य उत्तर देता है उत्तर कैसे दें
पीटर

मैं एक लूप के भीतर साजिश को विभाजित करने में असमर्थ था, और इसलिए सुझाव। प्रारंभ में, मैंने अपने कार्यान्वयन के साथ लूप के लिए अपने पूर्ण स्निपेट को लिखा था, लेकिन तब इसके खिलाफ निर्णय लिया। एक-एक सप्ताह में पूरा कोड अपडेट कर देंगे।
मयंक अग्रवाल

मैंने इसे पहली जगह में ही काउप्लॉट पैकेज का उपयोग करने की कोशिश की, लेकिन असफल रहा। मेरे त्वरित स्कैन पर, किसी ने लूप के लिए प्लॉटिंग समाधान का उल्लेख नहीं किया था और इसलिए मेरी टिप्पणी थी। अगर मैं गलत हूं तो मुझे कोई भी टिप्पणी दें।
मयंक अग्रवाल

यदि आपके उत्तर में कोड में एक लूप शामिल है जो अलग होगा।
पीटर

मैं इसे एक सप्ताह में यहां और कागले की पूरी परियोजना में अपडेट करूंगा। चीयर्स।
मयंक अग्रवाल

-3

cowplotपैकेज आप ऐसा करने के लिए एक अच्छा रास्ता देती है, एक तरह से है कि सूट प्रकाशन में।

x <- rnorm(100)
eps <- rnorm(100,0,.2)
A = qplot(x,3*x+eps, geom = c("point", "smooth"))+theme_gray()
B = qplot(x,2*x+eps, geom = c("point", "smooth"))+theme_gray()
cowplot::plot_grid(A, B, labels = c("A", "B"), align = "v")

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


3
यह भी देखें पैकेज लेखकों के बारे में अधिक विस्तृत जवाब और इसके बाद के संस्करण तर्क stackoverflow.com/a/31223588/199217
डेविड LeBauer
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.