2016-06-04 28 views
-1

Wenn wir nur Frequenztabelle gruppiert haben; zum BeispielBerechnen Sie Mittelwert, Median und Modus aus der gruppierten Häufigkeitstabelle

        (mk) (frequency) (cumulative freq) 
1        (37.9,43.1]  4  4 
2        (43.1,48.2] 16  20 
3        (48.2,53.3] 7  27 

Wie können wir Median, Modus und Mittelwert mit R berechnen?

Die theoretischen Beziehungen:

Mittlere

wir den Mittelwert jedes Intervalls suppose xi finden, fi, dessen Frequenz; bedeuten dann ist

sumof(xi*fi)/sumof(fi) 

für mein Beispiel

sum=4*(37.9+43.1)/2+16*(43.1+48.2)/2+7*(48.2+53.3)/2 
mean=mean/27=46.2 

Median

finden wir das Intervall, das seine kumulativen Frequenz
-sum über alle vorherigen Intervalle einschließlich dieses Intervall) gleich oder größer als n/2
-n ist die Gesamtfrequenz für unser Beispiel n = 27 und das Requir ed Intervall ist (43.1, 48.2)
dann, wenn wir lmin den Beginn dieses Intervalls hier verwenden lmin = 43.1, lmax das Ende dieses Intervalls, lmax = 48.2, fi die Häufigkeit dieses Intervalls, fi = 16, Fi die kumulative Frequenz = Fi 20 dann Median

median=43.1+((27/2-(20-16))/16) *(48.2-43.1)=46.128 

die Beziehung von Mode ist bekannt Median.

+1

Sie alles versucht haben? –

+0

Ich bin fest, wie Intervall (hier mk) von Zeichenfolge zu Intervall zu konvertieren, Ich weiß, wie Sie diese theoretische berechnen – joe

+0

Lassen Sie uns Ihre theoretischen Berechnungen sehen und vielleicht können wir dies auf Ihr Ergebnis anwenden. –

Antwort

1

Es scheint mir, Sie stecken in dem Schritt der Umwandlung der Textspalte in numerische Werte für lmin und lmax fest.

Einige Hantieren mit gsub() und strsplit() gibt Ihnen dies:

Zuerst replizieren die Daten:

dat <- read.table(text = " 
    (mk) (frequency) 
1 (37.9,43.1]  4 
2 (43.1,48.2] 16 
3 (48.2,53.3] 7") 

Dann das Zeichen Numerik konvertieren:

x <- gsub("[](]", "", dat$X.mk.) 
x <- strsplit(x, split = ",") 
x <- matrix(as.numeric(unlist(x)), 
      ncol = 2, 
      byrow = TRUE 
) 
colnames(x) <- c("lmin", "lmax") 

Das Ergebnis:

x 
    lmin lmax 
[1,] 37.9 43.1 
[2,] 43.1 48.2 
[3,] 48.2 53.3 
3

1) Mittel Lesen Sie die Daten in Zeichen Vektor L und ersetzen Sie alles, was keine Ziffer oder Punkt mit einem Leerzeichen ist. Dann lesen Sie es erneut, indem Sie den Datenrahmen DF erstellen, dessen Spalten V1, V2 und V3 sind. Berechne die Mittelwerte der Randwerte jeder Reihe und repliziere sie V3 mal mit einem Vektor r, der 4 + 16 + 7 Elemente enthält. Dann nimm den Mittelwert, Median und Modus davon. (Die Median- und Modusschätzungen davon sind möglicherweise nicht sehr gut.

)
# test data 
Lines <- "(mk) (frequency) 
(37.9,43.1]  4 
(43.1,48.2] 16 
(48.2,53.3]  7" 

# replace textConnection(Lines) with "myfile.txt", say 
L <- readLines(textConnection(Lines)) 
DF <- read.table(text = gsub("[^0-9.]", " ", L), skip = 1, as.is = TRUE) 

r <- with(DF, rep((V1 + V2)/2, V3)) 

mean(r) 
## [1] 46.209 

median(r) 
## [1] 45.65 

tab <- table(r) # frequency table 
as.numeric(names(tab))[which.max(tab)] 
## [1] 45.65 

Dies funktioniert auch direkt:

with(DF, weighted.mean((V1+V2)/2, V3)) 
## [1] 46.209 

2) Normale Ein weiterer Ansatz ist die Normalität (oder eine andere Verteilung) und zur Minimierung der negativen Wahrscheinlichkeit anzunehmen:

neglik <- function(x) { 
    m <- x[1] 
    s <- x[2] 
    with(DF, -prod(V3*(pnorm((V2-m)/s) - pnorm((V1-m)/s)))) 
} 
optim(c(mean(r), sd(r)), neglik)$par 
## [1] 45.6422 3.8841 

Wir kann dann den Mittelwert, den Median und den Modus als 45,6422 schätzen.

3) Stückweise einheitliche Eine mögliche Annahme ist, dass die pdf einheitlich innerhalb Frequenz reicht so:

pdf <- function(x) with(DF, { 
    if (length(x) > 1) return(sapply(x, pdf)) 
    if (x <= min(V1) || x >= max(V2)) return(0) 

    k <- sum(x > V1) 
    p <- V3/sum(V3)/(V2 - V1) 
    p[k] 
}) 

cdf <- function(x) { 
    if (length(x) == 1) integrate(pdf, -Inf, x)$value else sapply(x, cdf) 
} 

# or without integration - gives same answer as cdf 
cdf2 <- function(x) with(DF, { 
    xx <- unique(sort(c(V1, V2))) 
    yy <- c(0, cumsum(pdf((V1 + V2)/2) * (V2 - V1))) 
    approx(xx, yy, xout = x, rule = 2)$y 
}) 

# mean 
integrate(function(x) x * pdf(x), min(DF$V1), max(DF$V2))$value 
## [1] 46.20939 

# median - alternately could use cdf2 in place of cdf 
uniroot(function(m) cdf(m) - .5, range(c(DF$V1, DF$V2)))$root 
## [1] 46.12813 
+0

die Art der Berechnung Median ist nicht korrekt, es ist nicht notwendig Mittel ein Intervall – joe

+0

Was richtig ist, hängt davon ab, welche Annahmen wir treffen. Ich habe einige Variationen mit verschiedenen Annahmen hinzugefügt. –