我有一个按区域随时间变化的计数数据框。数据框的一行包含每列的计数总计。我想通过将每个列单元格除以相应列的计数总计,将数据框从计数转换为比例。有些列包含缺失的观察结果。我在下面使用嵌套完成了此操作for-loops,但怀疑可能有更简单的方法,也许使用lapply. 我在提取计数总计行时也遇到了麻烦。
我发布此内容的部分原因是,现在是我学习使用 apply 函数系列的时候了,我怀疑它们在这里可能有用,部分原因是我在创建计数总数向量时遇到了很多麻烦,并且怀疑使用它们会有所[[帮助。感谢您提供有关更有效地编写上述代码的任何建议。
my.data = read.table(text = "
state y1970 y1980 y1990 y2000
Alaska 4 6 NA 7
Iowa 10 20 30 40
Nevada 100 100 100 100
Ohio 50 60 NA 80
total 172 195 215 238
Wyoming 8 9 10 11
", sep = "", header = TRUE)
desired.result = read.table(text = "
state y1970 y1980 y1990 y2000
Alaska 0.02325581 0.03076923 NA 0.02941176
Iowa 0.05813953 0.10256410 0.13953488 0.16806723
Nevada 0.58139535 0.51282051 0.46511628 0.42016807
Ohio 0.29069767 0.30769231 NA 0.33613445
total 1.00000000 1.00000000 1.00000000 1.00000000
Wyoming 0.04651163 0.04615385 0.04651163 0.04621849
", sep = "", header = TRUE)
state <- as.vector(unlist(my.data[, 1]))
my.totals <- as.vector(unlist(my.data[ my.data$state=='total', 2:5]))
proportions <- matrix(NA, nrow=nrow(my.data), ncol=ncol(my.data))
proportions <- as.data.frame(proportions)
for(i in 1:nrow(my.data)) {
for(j in 1:ncol(my.data)) {
if(j==1) proportions[i,1] <- state[i]
if(j> 1) proportions[i,j] <- my.data[i,j] / my.totals[j-1]
}
}
colnames(proportions) <- names(my.data)
proportions
# state y1970 y1980 y1990 y2000
# 1 Alaska 0.02325581 0.03076923 NA 0.02941176
# 2 Iowa 0.05813953 0.10256410 0.13953488 0.16806723
# 3 Nevada 0.58139535 0.51282051 0.46511628 0.42016807
# 4 Ohio 0.29069767 0.30769231 NA 0.33613445
# 5 total 1.00000000 1.00000000 1.00000000 1.00000000
# 6 Wyoming 0.04651163 0.04615385 0.04651163 0.04621849
Run Code Online (Sandbox Code Playgroud)
大概是这样的:
df[, -1] <- lapply( df[ , -1], function(x) x/sum(x, na.rm=TRUE) )
Run Code Online (Sandbox Code Playgroud)
如果它是一个矩阵,你可以直接使用prop.table(mat). 然而,在这种情况下,您需要限制为仅处理数字列(通过排除第一个列)。
此外,我认为您需要排除“总计”行:
my.data[-5, -1] <- lapply( my.data[ -5 , -1], function(x){ x/sum(x, na.rm=TRUE)} )
my.data[ -5 , ]
state y1970 y1980 y1990 y2000
1 Alaska 0.02325581 0.03076923 NA 0.02941176
2 Iowa 0.05813953 0.10256410 0.21428571 0.16806723
3 Nevada 0.58139535 0.51282051 0.71428571 0.42016807
4 Ohio 0.29069767 0.30769231 NA 0.33613445
6 Wyoming 0.04651163 0.04615385 0.07142857 0.04621849
Run Code Online (Sandbox Code Playgroud)
替代方法:
> my.data[,-1] <-lapply( my.data[ , -1], function(x){ x/x[5] } )
> my.data
state y1970 y1980 y1990 y2000
1 Alaska 0.02325581 0.03076923 NA 0.02941176
2 Iowa 0.05813953 0.10256410 0.13953488 0.16806723
3 Nevada 0.58139535 0.51282051 0.46511628 0.42016807
4 Ohio 0.29069767 0.30769231 NA 0.33613445
5 total 1.00000000 1.00000000 1.00000000 1.00000000
6 Wyoming 0.04651163 0.04615385 0.04651163 0.04621849
Run Code Online (Sandbox Code Playgroud)
这显示了在两个边距上使用时 prop.table 将返回缺失值,然后分别在行和列上使用一个非常简单的矩阵:
> prop.table( matrix( c( 1,2,NA, 3),2) )
[,1] [,2]
[1,] NA NA
[2,] NA NA
> prop.table( matrix( c( 1,2,NA, 3),2), 1 )
[,1] [,2]
[1,] NA NA
[2,] 0.4 0.6
> prop.table( matrix( c( 1,2,NA, 3),2), 2 )
[,1] [,2]
[1,] 0.3333333 NA
[2,] 0.6666667 NA
Run Code Online (Sandbox Code Playgroud)