在 R 中有效地找到人口数据的中位数
Finding the median in population data Efficiently in R
假设人口数据
Age0 Age1 Age2 Age3 Age4 Age5 Age6 Age7 Age8 Age9 Age10 Age11
1 268818 261156 255699 249954 249764 250261 251251 252536 254123 256020 257009 256488
2 269489 261305 255394 251470 249123 249254 250075 251372 252931 254813 257074 258142
3 264620 258160 253543 250538 248914 248444 248895 250038 251642 253477 255653 258278
4 252431 262504 258066 254720 252358 250874 250049 249660 250167 251689 253781 255974
5 234872 240086 260846 258418 256334 254612 253263 252082 250855 250728 252172 254521
6 216095 228774 238871 259449 259030 258208 257122 255910 254370 252302 251543 252908
每个年龄段有几千人。即对于 Age0,第一年有 268818 个婴儿。我想获得每年的年龄中位数。到目前为止,我创建了一个低效的代码,我正在寻找一些帮助来让它变得更快。我使用的代码是这样的(注意:它对大量人群来说效率低下):
cells<-NULL
data<-MYdata[,3:103]
data<-data*1000 #i do this because of excel/R consider differently the . and ,
MedianMatrix<-matrix(nrow = nrow(data),ncol = 1)
for(i in 1:nrow(data)){
for(j in 1:ncol(data)){
print(c(i,j))
cell<-rep(j-1,times=data[i,j])
cells<-c(cells,cell)
}
print(length(cells))
MedianMatrix[i,1]<-median(cells)
cells<-NULL
}
MedianMatrix
任何 help/recommendations 让它 运行 更快?
谢谢。
您可以使用 apply
在一行中直接完成,这比两个 for
循环要快得多。
med_age <- apply(df, 1, function(x) median(rep(c(0:(length(x)-1)), x)))
基本上,对于每一行(年),您要重复每个年龄在您的行中出现的次数。然后,你直接计算中位数。
您可以计算各个年龄组的累积总和,然后找出总和小于或等于人口规模一半的最大年龄,而不是展开整个向量并找到中位数。
D <- read.table(header=TRUE, text="
Age0 Age1 Age2 Age3 Age4 Age5 Age6 Age7 Age8 Age9 Age10 Age11
268818 261156 255699 249954 249764 250261 251251 252536 254123 256020 257009 256488
269489 261305 255394 251470 249123 249254 250075 251372 252931 254813 257074 258142
264620 258160 253543 250538 248914 248444 248895 250038 251642 253477 255653 258278
252431 262504 258066 254720 252358 250874 250049 249660 250167 251689 253781 255974
234872 240086 260846 258418 256334 254612 253263 252082 250855 250728 252172 254521
216095 228774 238871 259449 259030 258208 257122 255910 254370 252302 251543 252908
")
apply(D, 1, function(x) {
cum <- c(0, cumsum(x))
which.max(cum[cum <= sum(x)/2])-1
})
假设人口数据
Age0 Age1 Age2 Age3 Age4 Age5 Age6 Age7 Age8 Age9 Age10 Age11
1 268818 261156 255699 249954 249764 250261 251251 252536 254123 256020 257009 256488
2 269489 261305 255394 251470 249123 249254 250075 251372 252931 254813 257074 258142
3 264620 258160 253543 250538 248914 248444 248895 250038 251642 253477 255653 258278
4 252431 262504 258066 254720 252358 250874 250049 249660 250167 251689 253781 255974
5 234872 240086 260846 258418 256334 254612 253263 252082 250855 250728 252172 254521
6 216095 228774 238871 259449 259030 258208 257122 255910 254370 252302 251543 252908
每个年龄段有几千人。即对于 Age0,第一年有 268818 个婴儿。我想获得每年的年龄中位数。到目前为止,我创建了一个低效的代码,我正在寻找一些帮助来让它变得更快。我使用的代码是这样的(注意:它对大量人群来说效率低下):
cells<-NULL
data<-MYdata[,3:103]
data<-data*1000 #i do this because of excel/R consider differently the . and ,
MedianMatrix<-matrix(nrow = nrow(data),ncol = 1)
for(i in 1:nrow(data)){
for(j in 1:ncol(data)){
print(c(i,j))
cell<-rep(j-1,times=data[i,j])
cells<-c(cells,cell)
}
print(length(cells))
MedianMatrix[i,1]<-median(cells)
cells<-NULL
}
MedianMatrix
任何 help/recommendations 让它 运行 更快? 谢谢。
您可以使用 apply
在一行中直接完成,这比两个 for
循环要快得多。
med_age <- apply(df, 1, function(x) median(rep(c(0:(length(x)-1)), x)))
基本上,对于每一行(年),您要重复每个年龄在您的行中出现的次数。然后,你直接计算中位数。
您可以计算各个年龄组的累积总和,然后找出总和小于或等于人口规模一半的最大年龄,而不是展开整个向量并找到中位数。
D <- read.table(header=TRUE, text="
Age0 Age1 Age2 Age3 Age4 Age5 Age6 Age7 Age8 Age9 Age10 Age11
268818 261156 255699 249954 249764 250261 251251 252536 254123 256020 257009 256488
269489 261305 255394 251470 249123 249254 250075 251372 252931 254813 257074 258142
264620 258160 253543 250538 248914 248444 248895 250038 251642 253477 255653 258278
252431 262504 258066 254720 252358 250874 250049 249660 250167 251689 253781 255974
234872 240086 260846 258418 256334 254612 253263 252082 250855 250728 252172 254521
216095 228774 238871 259449 259030 258208 257122 255910 254370 252302 251543 252908
")
apply(D, 1, function(x) {
cum <- c(0, cumsum(x))
which.max(cum[cum <= sum(x)/2])-1
})