在R

时间:2016-06-29 08:22:02

标签: r percentage calculated-columns

我正在开发一个数据集,其中包含每个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 food and 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

以上示例是摘录,我需要具备灵活性,以包含尽可能多的类别和国家/地区。

1 个答案:

答案 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功能转换结果。 sapply函数“循环”遍历grep搜索找到的所有组。在function(x, y, z)内,它会对属于该组的所有列进行子集化。这是第一个m[, gr == gr_total[1]]。因为R针对矢量化过程进行了优化,所以可以将矢量/矩阵除以矢量。试试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]。要添加列和行,请参阅rbindcbind