سؤال

أحاول رسم بيانات من النوع الشبكي باستخدام ggplot2 ثم تركيب توزيع طبيعي على بيانات العينة لتوضيح مدى بُعد البيانات الأساسية عن وضعها الطبيعي.أرغب في الحصول على التوزيع العادي في الأعلى ليكون له نفس المتوسط ​​والقيمة القياسية مثل اللوحة.

هنا مثال:

library(ggplot2)

#make some example data
dd<-data.frame(matrix(rnorm(144, mean=2, sd=2),72,2),c(rep("A",24),rep("B",24),rep("C",24)))
colnames(dd) <- c("x_value", "Predicted_value",  "State_CD")

#This works
pg <- ggplot(dd) + geom_density(aes(x=Predicted_value)) +  facet_wrap(~State_CD)
print(pg)

كل هذا يعمل بشكل رائع وينتج رسمًا بيانيًا رائعًا من ثلاث لوحات للبيانات.كيف يمكنني إضافة التوزيع العادي في الأعلى؟يبدو أنني سأستخدم stat_function، لكن هذا فشل:

#this fails
pg <- ggplot(dd) + geom_density(aes(x=Predicted_value)) + stat_function(fun=dnorm) +  facet_wrap(~State_CD)
print(pg)

يبدو أن وظيفة stat_function لا تتوافق مع ميزةfacet_wrap.كيف أجعل هذين الاثنين يلعبان بشكل جيد؟

------------يحرر---------

حاولت دمج أفكار من إجابتين أدناه وما زلت غير موجود:

باستخدام مزيج من الإجابتين يمكنني اختراق هذا معًا:

library(ggplot)
library(plyr)

#make some example data
dd<-data.frame(matrix(rnorm(108, mean=2, sd=2),36,2),c(rep("A",24),rep("B",24),rep("C",24)))
colnames(dd) <- c("x_value", "Predicted_value",  "State_CD")

DevMeanSt <- ddply(dd, c("State_CD"), function(df)mean(df$Predicted_value)) 
colnames(DevMeanSt) <- c("State_CD", "mean")
DevSdSt <- ddply(dd, c("State_CD"), function(df)sd(df$Predicted_value) )
colnames(DevSdSt) <- c("State_CD", "sd")
DevStatsSt <- merge(DevMeanSt, DevSdSt)

pg <- ggplot(dd, aes(x=Predicted_value))
pg <- pg + geom_density()
pg <- pg + stat_function(fun=dnorm, colour='red', args=list(mean=DevStatsSt$mean, sd=DevStatsSt$sd))
pg <- pg + facet_wrap(~State_CD)
print(pg)

والذي هو قريب حقا..باستثناء وجود خطأ ما في تخطيط التوزيعة العادي:

enter image description here

ما الخطأ الذي أفعله هنا؟

هل كانت مفيدة؟

المحلول

stat_function تم تصميمه لتراكب نفس الوظيفة في كل لوحة.(لا توجد طريقة واضحة لمطابقة معلمات الوظيفة مع اللوحات المختلفة).

وكما يقترح إيان، فإن أفضل طريقة هي توليد المنحنيات الطبيعية بنفسك، ورسمها على شكل رسم بياني متفرق مجموعة البيانات (هذا هو المكان الذي كنت تخطئ فيه من قبل - الدمج ليس له معنى في هذا المثال وإذا نظرت بعناية سترى أن هذا هو سبب حصولك على نمط سن المنشار الغريب).

إليك كيف سأبدأ في حل المشكلة:

dd <- data.frame(
  predicted = rnorm(72, mean = 2, sd = 2),
  state = rep(c("A", "B", "C"), each = 24)
) 

grid <- with(dd, seq(min(predicted), max(predicted), length = 100))
normaldens <- ddply(dd, "state", function(df) {
  data.frame( 
    predicted = grid,
    density = dnorm(grid, mean(df$predicted), sd(df$predicted))
  )
})

ggplot(dd, aes(predicted))  + 
  geom_density() + 
  geom_line(aes(y = density), data = normaldens, colour = "red") +
  facet_wrap(~ state) 

enter image description here

نصائح أخرى

أعتقد أنك بحاجة إلى تقديم المزيد من المعلومات.يبدو أن هذا يعمل:

 pg <- ggplot(dd, aes(Predicted_value)) ## need aesthetics in the ggplot
 pg <- pg + geom_density() 
 ## gotta provide the arguments of the dnorm
 pg <- pg + stat_function(fun=dnorm, colour='red',            
            args=list(mean=mean(dd$Predicted_value), sd=sd(dd$Predicted_value)))
 ## wrap it!
 pg <- pg + facet_wrap(~State_CD)
 pg

نحن نقدم نفس المعلمة المتوسطة وsd لكل لوحة.يتم ترك الحصول على الوسائل الخاصة باللوحة والانحرافات المعيارية كتمرين للقارئ* ;)

"*" وبعبارة أخرى، لست متأكدا من كيفية القيام بذلك ...

أعتقد أن أفضل رهان لك هو رسم الخط يدويًا باستخدام Geom_line.

dd<-data.frame(matrix(rnorm(144, mean=2, sd=2),72,2),c(rep("A",24),rep("B",24),rep("C",24)))
colnames(dd) <- c("x_value", "Predicted_value",  "State_CD")
dd$Predicted_value<-dd$Predicted_value*as.numeric(dd$State_CD) #make different by state

##Calculate means and standard deviations by level
means<-as.numeric(by(dd[,2],dd$State_CD,mean))
sds<-as.numeric(by(dd[,2],dd$State_CD,sd))

##Create evenly spaced evaluation points +/- 3 standard deviations away from the mean
dd$vals<-0
for(i in 1:length(levels(dd$State_CD))){
    dd$vals[dd$State_CD==levels(dd$State_CD)[i]]<-seq(from=means[i]-3*sds[i], 
                            to=means[i]+3*sds[i],
                            length.out=sum(dd$State_CD==levels(dd$State_CD)[i]))
}
##Create normal density points
dd$norm<-with(dd,dnorm(vals,means[as.numeric(State_CD)],
                        sds[as.numeric(State_CD)]))


pg <- ggplot(dd, aes(Predicted_value)) 
pg <- pg + geom_density() 
pg <- pg + geom_line(aes(x=vals,y=norm),colour="red") #Add in normal distribution
pg <- pg + facet_wrap(~State_CD,scales="free")
pg

إذا كنت لا ترغب في إنشاء رسم بياني خطي للتوزيع الطبيعي "يدويًا"، فلا تزال تستخدم stat_function، وإظهار الرسوم البيانية جنبًا إلى جنب - فيمكنك التفكير في استخدام وظيفة "multiplot" المنشورة في "Cookbook for R" كبديل لfacet_wrap.يمكنك نسخ الكود المتعدد إلى مشروعك من هنا.

بعد نسخ الكود قم بما يلي:

# Some fake data (copied from hadley's answer)
dd <- data.frame(
  predicted = rnorm(72, mean = 2, sd = 2),
  state = rep(c("A", "B", "C"), each = 24)
) 

# Split the data by state, apply a function on each member that converts it into a 
# plot object, and return the result as a vector.
plots <- lapply(split(dd,dd$state),FUN=function(state_slice){ 
  # The code here is the plot code generation. You can do anything you would 
  # normally do for a single plot, such as calling stat_function, and you do this 
  # one slice at a time.
  ggplot(state_slice, aes(predicted)) + 
    geom_density() + 
    stat_function(fun=dnorm, 
                  args=list(mean=mean(state_slice$predicted), 
                            sd=sd(state_slice$predicted)),
                  color="red")
})

# Finally, present the plots on 3 columns.
multiplot(plotlist = plots, cols=3)

enter image description here

إذا كنت على استعداد لاستخدام ggformula، فهذا أمر سهل جدًا.(من الممكن أيضًا المزج والمطابقة واستخدام ggformula لتراكب التوزيع فقط، ولكنني سأوضح النهج الكامل لـ ggformula.)

library(ggformula)
theme_set(theme_bw())

gf_dens( ~ Sepal.Length | Species, data = iris) %>%
  gf_fitdistr(color = "red") %>% 
  gf_fitdistr(dist = "gamma", color = "blue")

تم الإنشاء بتاريخ 2019-01-15 بواسطة حزمة ريبريكس (الإصدار 0.2.1)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top