根据R中的现有列创建多个百分比列

时间:2019-07-23 19:12:48

标签: r data.table

我想创建多个列,以显示col2col3Total中每个元素的百分比。我提供的代码仅占这些列中的百分比paste,而不是将其粘贴到新列中。 我已经在堆栈和Google上进行了搜索,但是找不到所需的答案。

样本数据:

data <- data.table(col1= c("A", "B", "C"),
                   col2= c(43,23,19),
                   col3= c(102,230,149))
data <- data[, Total := col2 + col3]
data <- janitor::adorn_title(data)

Output :

  col1 col2 col3 Total
    A   43  102   145
    B   23  230   253
    C   19  149   168
Total   85  481   566

我的百分比函数:

add_percent <- function(dt, col_no_percent, col_percent){
  dt <- dt[
    , c(.SD[, col_no_percent, with=FALSE],
        lapply(.SD[, col_percent, with=FALSE], function(x){
          paste0(x, format(round(x / sum(x) * 100 * 2, 1), nsmall = 1, decimal.mark = "."))

        }))
    ]
}

使用我的函数输出数据:

data <- add_percent(data, "col1", c("col2", "col3", "Total"))
    col1    col2     col3    Total
       A 43 50.6 102 21.2 145 25.6
       B 23 27.1 230 47.8 253 44.7
       C 19 22.4 149 31.0 168 29.7
   Total 85 100.0 481 100.0 566 100.0

我想要的数据输出:

  col1 col2 col3 Total col2.x col3.x Total.x
    A   43  102   145   50.6   21.2   25.6
    B   23  230   253   27.1   47.8   44.7
    C   19  149   168   22.4   31.0   29.7
Total   85  481   566  100.0  100.0  100.0

我的数据可能包含更多的列,因此所有新列都必须“自动”创建。因此,我想知道如何根据我的百分比函数或什至是更有效的方式来生成这些列。

谢谢。

2 个答案:

答案 0 :(得分:2)

初始数据。注意我删除了看门人步骤。最后将做这部分。

data <- data.table(col1= c("A", "B", "C"),
                   col2= c(43,23,19),
                   col3= c(102,230,149))
data <- data[, Total := col2 + col3]

为所有数字列添加百分比列,并添加“总计”行

cols <- names(data)[sapply(data, is.numeric)]

data[, paste0(cols, '_pct') := lapply(.SD, function(x) 100*x/sum(x))
   , .SDcols = cols]


adorn_totals(data)
 #  col1 col2 col3 Total  col2_pct  col3_pct Total_pct
 #     A   43  102   145  50.58824  21.20582  25.61837
 #     B   23  230   253  27.05882  47.81705  44.69965
 #     C   19  149   168  22.35294  30.97713  29.68198
 # Total   85  481   566 100.00000 100.00000 100.00000

答案 1 :(得分:1)

我知道这是一个data.table问题,但是dplyr有一个非常好的方法。因此,只需将其添加为可能的答案即可。

library(dplyr)

# this is your function (slightly changed)
as_perc <- function(x) {

  paste0(format(100 * (round(x/ sum(x),  2)), nsmall = 1, decimal.mark = "."), "%")

}

data %>%
   mutate_if(is.numeric, .funs = list(perc = ~ as_perc(.)))

  col1 col2 col3 Total col2_perc col3_perc Total_perc
1    A   43  102   145     51.0%     21.0%      26.0%
2    B   23  230   253     27.0%     48.0%      45.0%
3    C   19  149   168     22.0%     31.0%      30.0%