在R中的数据集中以相等的间隔计算总数的百分比
Calculating percentages of total at equal intervals in a data set in R
我正在处理一个数据集,其中包含每个 FMCG 类别的总数以及每个主要渠道的销售分布,如列中所示。摘录如下
CTY totsal MTsal GTsal Othsal totsal MTsal GTsal Othsal
food food food food deo deo deo deo
Arg 47313 19620 15052 12641 178 113 41 24
Aus 143140 85172 4634 53334 459 438 5 16
Bel 125399 82966 7818 34614 424 229 5 190
在我的输出数据集中,我想计算每 4 列中的总类别组的份额,例如totsal 食物和totsal deo。因此,这些份额必须为 1,而渠道的份额加起来必须是它们各自的价值。我正在查看的示例输出是:
CTY totshar MTshar GTshar Othshar totshar MTshar GTshar Othshar
food food food food deo deo deo deo
Arg 1 0.4 0.3 0.3 1.0 0.6 0.2 0.1
Aus 1 0.6 0.0 0.4 1.0 1.0 0.0 0.0
Bel 1 0.7 0.1 0.3 1.0 0.5 0.0 0.4
以上示例是摘录,我需要灵活地包含尽可能多的类别和国家/地区。
你可以这样做。
首先,我复制并粘贴了您的数据:
d <- read.table("clipboard",header=T)
d
CTY totsal MTsal GTsal Othsal totsal.1 MTsal.1 GTsal.1 Othsal.1
1 <NA> food food food food deo deo deo deo
2 Arg 47313 19620 15052 12641 178 113 41 24
3 Aus 143140 85172 4634 53334 459 438 5 16
4 Bel 125399 82966 7818 34614 424 229 5 190
然后我将数字转换为数字矩阵
m <- data.frame(d[-1, -1])
m <- t(apply(m, 1, function(x) as.numeric(as.character(x))))
m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
2 47313 19620 15052 12641 178 113 41 24
3 143140 85172 4634 53334 459 438 5 16
4 125399 82966 7818 34614 424 229 5 190
我使用 grep
搜索了总列,并为列组创建了一个索引 gr
。请注意,total
列必须始终是组的第一列。组值的总数可以变化。
gr_total <- grep("tot", colnames(d)[-1])
gr <- sort(rep(gr_total, 4))
我使用 sapply
计算每组的百分比并使用 matrix
函数转换结果。应用函数 "loops" 遍历 grep
搜索找到的所有组。在 function(x, y, z)
中,它对属于该组的所有列进行子集化。这里为第一个m[, gr == gr_total[1]]
。因为 R 针对矢量化过程进行了优化,所以您可以将 vector/matrix 除以矢量。尝试 m[, gr == gr_total[1]]/m[ , gr_total[1]]
。对于 matrix()
函数,请参阅 ?matrix
并检查 sapply
输出。
matrix(sapply(gr_total, function(x, y, z) z[, y==x]/z[, x], gr, m), nrow(m), ncol(m), byrow = FALSE)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 0.4146852 0.31813666 0.2671782 1 0.6348315 0.23033708 0.13483146
[2,] 1 0.5950258 0.03237390 0.3726003 1 0.9542484 0.01089325 0.03485839
[3,] 1 0.6616161 0.06234499 0.2760309 1 0.5400943 0.01179245 0.44811321
可以使用round
函数四舍五入一位数。假设您将结果保存在 m1
中,请使用 round(m1, 1)
。
Colnames 可以替换为 colnames(m1) <- colnames(d)[-1]
。要添加列和行,请参阅 rbind
和 cbind
。
我正在处理一个数据集,其中包含每个 FMCG 类别的总数以及每个主要渠道的销售分布,如列中所示。摘录如下
CTY totsal MTsal GTsal Othsal totsal MTsal GTsal Othsal
food food food food deo deo deo deo
Arg 47313 19620 15052 12641 178 113 41 24
Aus 143140 85172 4634 53334 459 438 5 16
Bel 125399 82966 7818 34614 424 229 5 190
在我的输出数据集中,我想计算每 4 列中的总类别组的份额,例如totsal 食物和totsal deo。因此,这些份额必须为 1,而渠道的份额加起来必须是它们各自的价值。我正在查看的示例输出是:
CTY totshar MTshar GTshar Othshar totshar MTshar GTshar Othshar
food food food food deo deo deo deo
Arg 1 0.4 0.3 0.3 1.0 0.6 0.2 0.1
Aus 1 0.6 0.0 0.4 1.0 1.0 0.0 0.0
Bel 1 0.7 0.1 0.3 1.0 0.5 0.0 0.4
以上示例是摘录,我需要灵活地包含尽可能多的类别和国家/地区。
你可以这样做。 首先,我复制并粘贴了您的数据:
d <- read.table("clipboard",header=T)
d
CTY totsal MTsal GTsal Othsal totsal.1 MTsal.1 GTsal.1 Othsal.1
1 <NA> food food food food deo deo deo deo
2 Arg 47313 19620 15052 12641 178 113 41 24
3 Aus 143140 85172 4634 53334 459 438 5 16
4 Bel 125399 82966 7818 34614 424 229 5 190
然后我将数字转换为数字矩阵
m <- data.frame(d[-1, -1])
m <- t(apply(m, 1, function(x) as.numeric(as.character(x))))
m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
2 47313 19620 15052 12641 178 113 41 24
3 143140 85172 4634 53334 459 438 5 16
4 125399 82966 7818 34614 424 229 5 190
我使用 grep
搜索了总列,并为列组创建了一个索引 gr
。请注意,total
列必须始终是组的第一列。组值的总数可以变化。
gr_total <- grep("tot", colnames(d)[-1])
gr <- sort(rep(gr_total, 4))
我使用 sapply
计算每组的百分比并使用 matrix
函数转换结果。应用函数 "loops" 遍历 grep
搜索找到的所有组。在 function(x, y, z)
中,它对属于该组的所有列进行子集化。这里为第一个m[, gr == gr_total[1]]
。因为 R 针对矢量化过程进行了优化,所以您可以将 vector/matrix 除以矢量。尝试 m[, gr == gr_total[1]]/m[ , gr_total[1]]
。对于 matrix()
函数,请参阅 ?matrix
并检查 sapply
输出。
matrix(sapply(gr_total, function(x, y, z) z[, y==x]/z[, x], gr, m), nrow(m), ncol(m), byrow = FALSE)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 0.4146852 0.31813666 0.2671782 1 0.6348315 0.23033708 0.13483146
[2,] 1 0.5950258 0.03237390 0.3726003 1 0.9542484 0.01089325 0.03485839
[3,] 1 0.6616161 0.06234499 0.2760309 1 0.5400943 0.01179245 0.44811321
可以使用round
函数四舍五入一位数。假设您将结果保存在 m1
中,请使用 round(m1, 1)
。
Colnames 可以替换为 colnames(m1) <- colnames(d)[-1]
。要添加列和行,请参阅 rbind
和 cbind
。