从分组频率表

时间:2016-06-04 07:26:16

标签: r media mean mode

如果我们只有频率表分组;例如

                                    (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 / 2
-n是总频率 - 对于我们的例子,n = 27,所需的间隔是(43.1,48.2)
然后如果我们使用lmin这个间隔的开始这里lmin = 43.1,lmax这个间隔的结束,lmax = 48.2,fi这个间隔的频率,fi = 16,Fi是累积频率,Fi = 20然后 中位数是

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

模式的关系对于中位数是熟悉的。

2 个答案:

答案 0 :(得分:3)

1)意味着将数据读入字符向量L,并用空格替换不是数字或点的所有内容。然后重新阅读它,创建数据框DF,其列为V1V2V3。计算每行的边界值的平均值并复制它们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)

在我看来,您仍然坚持将文本列转换为lminlmax的数值。

一些摆弄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