ที่อื่นในหัวข้อนี้ฉันเสนอวิธีแก้ปัญหาแบบง่าย ๆ แต่ค่อนข้างจะเป็นการแบ่งย่อยคะแนน มันรวดเร็ว แต่ต้องมีการทดลองเพื่อสร้างแปลงที่ยอดเยี่ยม วิธีแก้ปัญหาที่จะอธิบายคือลำดับความสำคัญช้าลง (ใช้เวลาสูงสุด 10 วินาทีสำหรับ 1.2 ล้านจุด) แต่ปรับได้อัตโนมัติ สำหรับชุดข้อมูลขนาดใหญ่มันควรจะให้ผลลัพธ์ที่ดีในครั้งแรกและทำได้อย่างรวดเร็วพอสมควร
Dn
( x , y)เสื้อY
มีรายละเอียดบางอย่างที่จะดูแลโดยเฉพาะเพื่อรับมือกับชุดข้อมูลที่มีความยาวต่างกัน ฉันทำสิ่งนี้โดยการแทนที่อันที่สั้นกว่าโดยควอนไทล์ที่สอดคล้องกับอันที่ยาวกว่า: ด้วยเหตุนี้การประมาณเชิงเส้นเชิงเส้นของ EDF ของอันที่สั้นกว่านั้นจะถูกใช้แทนค่าข้อมูลจริง ("สั้นกว่า" และ "ยาวกว่า" สามารถกลับด้านได้โดยการตั้งค่าuse.shortest=TRUE
)
นี่คือการR
ดำเนินการ
qq <- function(x0, y0, t.y=0.0005, use.shortest=FALSE) {
qq.int <- function(x,y, i.min,i.max) {
# x, y are sorted and of equal length
n <-length(y)
if (n==1) return(c(x=x, y=y, i=i.max))
if (n==2) return(cbind(x=x, y=y, i=c(i.min,i.max)))
beta <- ifelse( x[1]==x[n], 0, (y[n] - y[1]) / (x[n] - x[1]))
alpha <- y[1] - beta*x[1]
fit <- alpha + x * beta
i <- median(c(2, n-1, which.max(abs(y-fit))))
if (abs(y[i]-fit[i]) > thresh) {
assemble(qq.int(x[1:i], y[1:i], i.min, i.min+i-1),
qq.int(x[i:n], y[i:n], i.min+i-1, i.max))
} else {
cbind(x=c(x[1],x[n]), y=c(y[1], y[n]), i=c(i.min, i.max))
}
}
assemble <- function(xy1, xy2) {
rbind(xy1, xy2[-1,])
}
#
# Pre-process the input so that sorting is done once
# and the most detail is extracted from the data.
#
is.reversed <- length(y0) < length(x0)
if (use.shortest) is.reversed <- !is.reversed
if (is.reversed) {
y <- sort(x0)
n <- length(y)
x <- quantile(y0, prob=(1:n-1)/(n-1))
} else {
y <- sort(y0)
n <- length(y)
x <- quantile(x0, prob=(1:n-1)/(n-1))
}
#
# Convert the relative threshold t.y into an absolute.
#
thresh <- t.y * diff(range(y))
#
# Recursively obtain points on the QQ plot.
#
xy <- qq.int(x, y, 1, n)
if (is.reversed) cbind(x=xy[,2], y=xy[,1], i=xy[,3]) else xy
}
ตัวอย่างฉันใช้ข้อมูลที่จำลองตามคำตอบก่อนหน้าของฉัน (โดยมีค่าสูงมากและถูกy
ปนเปื้อนในx
เวลานี้):
set.seed(17)
n.x <- 1.21 * 10^6
n.y <- 1.20 * 10^6
k <- floor(0.01*n.x)
x <- c(rnorm(n.x-k), rnorm(k, mean=2, sd=2))
x <- x[x <= -3 | x >= -2.5]
y <- c(rbeta(n.y, 10,13), 1)
ลองพล็อตหลาย ๆ เวอร์ชันโดยใช้ค่าที่น้อยลงและเล็กลงของเกณฑ์ ด้วยค่า. 0005 และแสดงบนจอภาพสูง 1,000 พิกเซลเราจะรับประกันข้อผิดพลาดไม่เกินครึ่งพิกเซลแนวตั้งทุกที่บนพล็อต สิ่งนี้แสดงเป็นสีเทา (มีเพียง 522 คะแนนรวมกับส่วนของเส้น) การประมาณค่าที่หยาบจะถูกพล็อตที่ด้านบนของมัน: เป็นครั้งแรกในสีดำ, จากนั้นในสีแดง (จุดสีแดงจะเป็นเซตย่อยของสีดำ ช่วงเวลาตั้งแต่ 6.5 (สีน้ำเงิน) ถึง 10 วินาที (สีเทา) เนื่องจากว่าพวกมันมีอัตราส่วนที่ดีดังนั้นหนึ่งอาจใช้พิกเซลประมาณครึ่งเดียวเป็นค่าเริ่มต้นสากลสำหรับเกณฑ์ ( เช่น 1/2000 สำหรับจอภาพสูง 1,000 พิกเซล) และทำได้ด้วย
qq.1 <- qq(x,y)
plot(qq.1, type="l", lwd=1, col="Gray",
xlab="x", ylab="y", main="Adaptive QQ Plot")
points(qq.1, pch=".", cex=6, col="Gray")
points(qq(x,y, .01), pch=23, col="Black")
points(qq(x,y, .03), pch=22, col="Red")
points(qq(x,y, .1), pch=19, col="Blue")
แก้ไข
ฉันได้แก้ไขรหัสต้นฉบับสำหรับqq
เพื่อส่งกลับคอลัมน์ที่สามของดัชนีไปเป็นระยะเวลาที่สั้นที่สุด (หรือสั้นที่สุดตามที่ระบุ) ของสองอาร์เรย์x
และy
สอดคล้องกับจุดที่เลือกไว้ ดัชนีเหล่านี้ชี้ไปที่ค่า "น่าสนใจ" ของข้อมูลและอาจเป็นประโยชน์สำหรับการวิเคราะห์ต่อไป
ฉันยังลบข้อผิดพลาดที่เกิดขึ้นด้วยค่าซ้ำของx
(ซึ่งทำให้beta
ไม่ได้กำหนด)
approx()
ฟังก์ชั่นเข้ามามีบทบาทในqqplot()
ฟังก์ชั่น