如何将百分比列添加到 R 中数据框中的每一列

how to add percent column to every other column in dataframe in R

我有一个计数数据框,我想在每个计数列之后添加 % 列。

df <- data.frame(name= c("Ji", "Ka", "Na", "Po"),
                 `a(N)`= c(1,4,5,2),
                 `b(N)`=c(0.5,04,0.8,0.3),
                 `c(N)`= c(41,49,48,42))

df
  name a.N. b.N. c.N.
1   Ji    1  0.5   41
2   Ka    4  4.0   49
3   Na    5  0.8   48
4   Po    2  0.3   42

所以我想要类似

的东西
df <- df %>%
  add_column(`a(%)` = df$a.N./sum(df$a.N.), .after= "a.N.") %>%
  add_column(`b(%)` = df$b.N./sum(df$b.N.), .after= "b.N.") %>%
  add_column(`c(%)` = df$c.N./sum(df$c.N.), .after= "c.N.")

  name a.N.       a(%) b.N.       b(%) c.N.      c(%)
1   Ji    1 0.08333333  0.5 0.08928571   41 0.2277778
2   Ka    4 0.33333333  4.0 0.71428571   49 0.2722222
3   Na    5 0.41666667  0.8 0.14285714   48 0.2666667
4   Po    2 0.16666667  0.3 0.05357143   42 0.2333333

我的实际数据框有更多列,因此一一应用 add_column 没有意义。有没有办法用更少的代码行来获得百分比列?

我们可以用across

library(dplyr)
library(stringr)
df %>% 
   mutate(across(-name, ~ .x/sum(.x),
    .names = "{str_remove(.col, fixed('.N.'))}(%)"))  %>%
   select(name, gtools::mixedsort(names(.)[-1]))

-输出

   name a.N.       a(%) b.N.       b(%) c.N.      c(%)
1   Ji    1 0.08333333  0.5 0.08928571   41 0.2277778
2   Ka    4 0.33333333  4.0 0.71428571   49 0.2722222
3   Na    5 0.41666667  0.8 0.14285714   48 0.2666667
4   Po    2 0.16666667  0.3 0.05357143   42 0.2333333

使用 proportions.

cbind(df, sapply(df[-1], proportions))[c(1, 2, 5, 3, 6, 4, 7)]
#   name a.N.     a.N..1 b.N.     b.N..1 c.N.    c.N..1
# 1   Ji    1 0.08333333  0.5 0.08928571   41 0.2277778
# 2   Ka    4 0.33333333  4.0 0.71428571   49 0.2722222
# 3   Na    5 0.41666667  0.8 0.14285714   48 0.2666667
# 4   Po    2 0.16666667  0.3 0.05357143   42 0.2333333