问题描述
我有以下数据框
df <- data.frame( Country = c("AL","AL","FR","UK","UK"),LT5F = c(4,2,1,3,4,2),LT5M = c(5,7,0),LT5T = c(9,5,8,Y9t14F = c(3,5),Y9t14M = c(1,6,3),Y9t14T = c(4,9,8))
我希望对每第 n 个观测值(在我的实际数据中为 1100)求和,并将 1100 范围内的每个数字除以总和。在我的例子中,n = 4。每 4 次观察的每一列的总和是:
Sum4thObs <- data.frame( L
LT5F = c(10,7),LT5M = c(14,10,6),LT5T = c(24,18,13),Y9t14F = c(9,19,Y9t14M = c(11,16,14),Y9t14T = c(20,35,27))
我想要的是一个数据框,其中每个单元格都除以“n”-long 的范围之和。
我梦想中的数据框是这样的:
dfdream <- data.frame( Country = c("AL",LT5F = c(4/10,2/10,1/10,3/10,2/8,1/8,4/8,2/7,1/7,2/7),LT5M = c(5/14,3/14,4/14,2/14,0/10,7/10,3/6,2/6,1/6,0/6),LT5T = c(),Y9t14F = c(),Y9t14M = c(),Y9t14T = c())
等等...
此外,我有 50 个列,其中包含 100 个唯一的国家/地区标识符(示例中的 AL、FR、UK = 3)。有没有一种聪明而简单的方法可以将每个单元格除以 1:1100 的总和?
我希望我的问题很清楚。谢谢。
解决方法
您可以通过以下方式实现您的“梦想数据框”:
library(dplyr)
df %>%
group_by(Country) %>%
mutate(across(LT5F:Y9t14T,prop.table)) %>%
ungroup
# Country LT5F LT5M LT5T Y9t14F Y9t14M Y9t14T
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 AL 0.4 0.357 0.375 0.333 0.0909 0.2
# 2 AL 0.2 0.214 0.208 0.222 0.455 0.35
# 3 AL 0.1 0.286 0.208 0.111 0.273 0.2
# 4 AL 0.3 0.143 0.208 0.333 0.182 0.25
# 5 FR 0.25 0.2 0.222 0.263 0.25 0.257
# 6 FR 0.125 0.1 0.111 0.158 0.375 0.257
# 7 FR 0.5 0 0.222 0.368 0.0625 0.229
# 8 FR 0.125 0.7 0.444 0.211 0.312 0.257
# 9 UK 0.286 0.5 0.385 0.231 0.214 0.222
#10 UK 0.143 0.333 0.231 0.231 0.286 0.259
#11 UK 0.286 0.167 0.231 0.154 0.286 0.222
#12 UK 0.286 0 0.154 0.385 0.214 0.296
如果您有 NA
,则可以使用:
library(dplyr)
df %>%
group_by(Country) %>%
mutate(across(LT5F:Y9t14T,~./sum(.,na.rm = TRUE))) %>%
ungroup
,
一个简单的基本解决方案:
假设 df
是您的示例数据集
i <- 1:12
li <- split(i,cut(i,3,labels = FALSE))
myfun <- function(i){
a <- df[i,-1]
b <- colSums(df[i,-1])
result <- mapply("/",a,b)
return(result)
}
dfdream <- as.data.frame(do.call(rbind,lapply(li,myfun)))
dfdream$County <- df$Country
现在可以了:
dfdream
LT5F LT5M LT5T Y9t14F Y9t14M Y9t14T County
1 0.4000000 0.3571429 0.3750000 0.3333333 0.09090909 0.2000000 AL
2 0.2000000 0.2142857 0.2083333 0.2222222 0.45454545 0.3500000 AL
3 0.1000000 0.2857143 0.2083333 0.1111111 0.27272727 0.2000000 AL
4 0.3000000 0.1428571 0.2083333 0.3333333 0.18181818 0.2500000 AL
5 0.2500000 0.2000000 0.2222222 0.2631579 0.25000000 0.2571429 FR
6 0.1250000 0.1000000 0.1111111 0.1578947 0.37500000 0.2571429 FR
7 0.5000000 0.0000000 0.2222222 0.3684211 0.06250000 0.2285714 FR
8 0.1250000 0.7000000 0.4444444 0.2105263 0.31250000 0.2571429 FR
9 0.2857143 0.5000000 0.3846154 0.2307692 0.21428571 0.2222222 UK
10 0.1428571 0.3333333 0.2307692 0.2307692 0.28571429 0.2592593 UK
11 0.2857143 0.1666667 0.2307692 0.1538462 0.28571429 0.2222222 UK
12 0.2857143 0.0000000 0.1538462 0.3846154 0.21428571 0.2962963 UK
,
按国家/地区获取比例的data.table
解决方案:
library(data.table)
dtPropByCountry <- setDT(df)[,lapply(.SD,function(x) x/sum(x,na.rm = TRUE)),by = Country,.SDcols = 2:ncol(df)]