การปรับเส้นโค้งความหนาแน่นให้พอดีกับฮิสโตแกรมใน R


95

มีฟังก์ชันใน R ที่พอดีกับเส้นโค้งของฮิสโตแกรมหรือไม่?

สมมติว่าคุณมีฮิสโตแกรมต่อไปนี้

hist(c(rep(65, times=5), rep(25, times=5), rep(35, times=10), rep(45, times=4)))

มันดูธรรมดา แต่มันเบ้ ฉันต้องการพอดีกับเส้นโค้งปกติที่เอียงเพื่อพันรอบฮิสโตแกรมนี้

คำถามนี้ค่อนข้างธรรมดา แต่ดูเหมือนจะหาคำตอบสำหรับ R บนอินเทอร์เน็ตไม่ได้


คุณต้องการหา m และ s เพื่อให้การแจกแจงแบบเกาส์ N (m, s) เหมาะกับข้อมูลของคุณหรือไม่?
SteinNorheim

ฉันไม่แน่ใจว่ามันหมายถึงอะไร ... > _>
user5243421

10
@mathee: ฉันคิดว่าเขาหมายถึง m = mean และ s = ส่วนเบี่ยงเบนมาตรฐาน การแจกแจงแบบเกาส์เซียนเป็นอีกชื่อหนึ่งสำหรับการแจกแจงแบบปกติ
Peter Mortensen

คำตอบ:


156

ถ้าฉันเข้าใจคำถามของคุณถูกต้องคุณอาจต้องการค่าประมาณความหนาแน่นพร้อมกับฮิสโตแกรม:

X <- c(rep(65, times=5), rep(25, times=5), rep(35, times=10), rep(45, times=4))
hist(X, prob=TRUE)            # prob=TRUE for probabilities not counts
lines(density(X))             # add a density estimate with defaults
lines(density(X, adjust=2), lty="dotted")   # add another "smoother" density

แก้ไขในภายหลัง:

นี่คือเวอร์ชันแต่งตัวเพิ่มเติมเล็กน้อย:

X <- c(rep(65, times=5), rep(25, times=5), rep(35, times=10), rep(45, times=4))
hist(X, prob=TRUE, col="grey")# prob=TRUE for probabilities not counts
lines(density(X), col="blue", lwd=2) # add a density estimate with defaults
lines(density(X, adjust=2), lty="dotted", col="darkgreen", lwd=2) 

พร้อมกับกราฟที่สร้างขึ้น:

ใส่คำอธิบายภาพที่นี่


3
+1 - คุณสามารถทำวิธีอื่น ๆ ได้เช่นการปรับพล็อตความหนาแน่นให้พอดีกับฮิสโตแกรมหรือไม่
vonjd

2
ฉันขอแนะนำให้ระบุพารามิเตอร์เพิ่มเติมlines(density(X,na.rm= TRUE)เนื่องจากเวกเตอร์อาจมีค่า NA
Anirudh

30

สิ่งนั้นเป็นเรื่องง่ายด้วย ggplot2

library(ggplot2)
dataset <- data.frame(X = c(rep(65, times=5), rep(25, times=5), 
                            rep(35, times=10), rep(45, times=4)))
ggplot(dataset, aes(x = X)) + 
  geom_histogram(aes(y = ..density..)) + 
  geom_density()

หรือเลียนแบบผลลัพธ์จากการแก้ปัญหาของเดิร์ก

ggplot(dataset, aes(x = X)) + 
  geom_histogram(aes(y = ..density..), binwidth = 5) + 
  geom_density()

28

นี่คือวิธีที่ฉันทำ:

foo <- rnorm(100, mean=1, sd=2)
hist(foo, prob=TRUE)
curve(dnorm(x, mean=mean(foo), sd=sd(foo)), add=TRUE)

การออกกำลังกายโบนัสคือการทำเช่นนี้กับแพ็คเกจ ggplot2 ...


อย่างไรก็ตามหากคุณต้องการบางสิ่งที่เบ้คุณสามารถทำตัวอย่างความหนาแน่นจากด้านบนแปลงข้อมูลของคุณ (เช่น foo.log & lt; - log (foo) แล้วลองทำตามด้านบน) หรือลองใช้การกระจายแบบเบ้เช่น gamma หรือ lognormal (lognormal เทียบเท่ากับการบันทึกและปรับค่าปกติ btw)
John Johnson

2
แต่นั่นยังคงต้องมีการประมาณค่าพารามิเตอร์ของการแจกแจงของคุณก่อน
Dirk Eddelbuettel

สิ่งนี้ทำให้ห่างไกลจากการพูดคุยเกี่ยวกับ R เนื่องจากเรากำลังเข้าสู่สถิติเชิงทฤษฎีมากขึ้น แต่คุณอาจลองใช้ลิงก์นี้สำหรับ Gamma: en.wikipedia.org/wiki/Gamma_distribution#Parameter_estimation สำหรับ lognormal ให้ใช้ log (สมมติว่า ข้อมูลทั้งหมดเป็นค่าบวก) และทำงานกับข้อมูลที่แปลงบันทึก สำหรับคนที่คลั่งไคล้ฉันคิดว่าคุณจะต้องทำงานกับตำราสถิติ
John Johnson

3
ฉันคิดว่าคุณเข้าใจผิดว่าทั้งโปสเตอร์ต้นฉบับและคำตอบอื่น ๆ ทั้งหมดค่อนข้างมีเนื้อหาที่จะใช้การประมาณที่ไม่ใช่พารามิเตอร์เช่นฮิสโตแกรมแบบโรงเรียนเก่าหรือการประมาณค่าความหนาแน่นที่อิงจากข้อมูลที่ค่อนข้างทันสมัยกว่า การประมาณค่าพารามิเตอร์นั้นดีมากหากคุณมีเหตุผลที่ดีที่จะสงสัยว่ามีการกระจาย แต่นั่นไม่ใช่กรณีที่นี่
Dirk Eddelbuettel

11

Dirkได้อธิบายวิธีการพล็อตฟังก์ชันความหนาแน่นบนฮิสโตแกรม แต่บางครั้งคุณอาจต้องการใช้สมมติฐานที่ชัดเจนยิ่งขึ้นของการแจกแจงแบบปกติและพล็อตที่เบ้แทนที่จะเป็นความหนาแน่น คุณสามารถประมาณพารามิเตอร์ของการแจกแจงและลงจุดโดยใช้แพ็คเกจ sn :

> sn.mle(y=c(rep(65, times=5), rep(25, times=5), rep(35, times=10), rep(45, times=4)))
$call
sn.mle(y = c(rep(65, times = 5), rep(25, times = 5), rep(35, 
    times = 10), rep(45, times = 4)))

$cp
    mean     s.d. skewness 
41.46228 12.47892  0.99527 

พล็อตข้อมูลแบบกระจายแบบเอียงปกติ

สิ่งนี้อาจทำงานได้ดีขึ้นกับข้อมูลที่มีความเบ้มากกว่าปกติ:

พล็อตเรื่องธรรมดาอีกเรื่องหนึ่ง


3

ฉันมีปัญหาเดียวกัน แต่วิธีแก้ปัญหาของเดิร์กไม่ได้ผล ฉันได้รับคำเตือนนี้ทุกครั้ง

"prob" is not a graphical parameter

ฉันอ่าน?histและพบเกี่ยวกับfreq: a logical vector set TRUE by default.

รหัสที่ใช้ได้สำหรับฉันคือ

hist(x,freq=FALSE)
lines(density(x),na.rm=TRUE)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.