如果我们只有频率表分组;例如
(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
我们如何使用R?
计算中位数,模式和平均值理论关系:
平均数
我们找到每个区间的平均值,假设xi,其频率为fi; 然后意思是
sumof(xi*fi)/sumof(fi)
我的例子
sum=4*(37.9+43.1)/2+16*(43.1+48.2)/2+7*(48.2+53.3)/2
mean=mean/27=46.2
中值
我们找到了他累积频率的间隔 -sum包括此间隔的所有先前间隔)等于或大于n / 2median=43.1+( ( 27/2-(20-16) )/16 ) *(48.2-43.1)=46.128
模式的关系对于中位数是熟悉的。
答案 0 :(得分:3)
1)意味着将数据读入字符向量L
,并用空格替换不是数字或点的所有内容。然后重新阅读它,创建数据框DF
,其列为V1
,V2
和V3
。计算每行的边界值的平均值并复制它们V3
次,给出包含4 + 16 + 7个元素的向量r
。然后取平均值,中位数和模式。 (由此得出的中位数和模式估计可能不是很好。)
# 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
这也可以直接使用:
with(DF, weighted.mean((V1+V2)/2, V3))
## [1] 46.209
2)正常另一种方法是假设正态(或其他分布)并最小化负面可能性:
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
然后我们可以估计平均值,中位数和模式为45.6422。
3)分段均匀一个可能的假设是pdf在频率范围内是均匀的,所以:
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
答案 1 :(得分:1)
在我看来,您仍然坚持将文本列转换为lmin
和lmax
的数值。
一些摆弄gsub()
和strsplit()
的人会给你:
首先,复制数据:
dat <- read.table(text = "
(mk) (frequency)
1 (37.9,43.1] 4
2 (43.1,48.2] 16
3 (48.2,53.3] 7")
然后,将角色转换为数字:
x <- gsub("[](]", "", dat$X.mk.)
x <- strsplit(x, split = ",")
x <- matrix(as.numeric(unlist(x)),
ncol = 2,
byrow = TRUE
)
colnames(x) <- c("lmin", "lmax")
结果:
x
lmin lmax
[1,] 37.9 43.1
[2,] 43.1 48.2
[3,] 48.2 53.3