如何根据不同列的值创建新列并计算 R 中另一个数字列的百分比值?

Shi*_*sad 5 r dataframe dplyr data-wrangling

示例数据框:

no <- rep(1:5, each=2)
type <- rep(LETTERS[1:2], times=5)
set.seed(4)
value <- round(runif(10, 10, 30))

df <- data.frame(no, type, value)
Run Code Online (Sandbox Code Playgroud)
df

    no type value
1   1    A    22
2   1    B    10
3   2    A    16
4   2    B    16
5   3    A    26
6   3    B    15
7   4    A    24
8   4    B    28
9   5    A    29
10  5    B    11
Run Code Online (Sandbox Code Playgroud)

现在我想要的是计算每种类型(A 或 B)的 % 值并创建单独的列。期望的输出是这样的:

 no    pct_A    pct_B total_value
1  1 68.75000 31.25000          32
2  2 50.00000 50.00000          32
3  3 63.41463 36.58537          41
4  4 46.15385 53.84615          52
5  5 72.50000 27.50000          40

Run Code Online (Sandbox Code Playgroud)

到目前为止我已经尝试过的(这给出了正确的输出,但该过程似乎非常次优):

df %>%
  group_by(no) %>%
  mutate(total_value= sum(value))-> df

df %>%
  mutate(pct_A=ifelse(type=='A', (value/total_value) *100, 0),
         pct_B=ifelse(type=='B', (value/total_value) *100, 0)) %>%
  group_by(no) %>%
  summarise(pct_A=sum(pct_A),
            pct_B=sum(pct_B)) %>%
  ungroup() %>%
  merge(df) %>%
  distinct(no, .keep_all = T) %>%
  select(-type, -value)
Run Code Online (Sandbox Code Playgroud)

有更好的方法吗?特别是使用dplyr

我也寻找其他答案,但没有帮助。这个更接近:

R 根据另一列的因子水平创建新的值列

Ron*_*hah 1

对于每个no,我们可以计算sum和比率,然后获得宽格式的数据。

library(dplyr)
library(tidyr)

df %>%
  group_by(no) %>%
  mutate(total_value = sum(value),
         value = prop.table(value) * 100) %>%
  ungroup %>%
  pivot_wider(names_from = type, values_from = value, names_prefix = 'pct_')

#     no total_value pct_A pct_B
#  <int>       <dbl> <dbl> <dbl>
#1     1          32  68.8  31.2
#2     2          32  50    50  
#3     3          41  63.4  36.6
#4     4          52  46.2  53.8
#5     5          40  72.5  27.5
Run Code Online (Sandbox Code Playgroud)