R语言 如何将变量值更新为当前值(当前值 * 100/ colsums())

sshcrbum  于 2023-06-19  发布在  其他
关注(0)|答案(2)|浏览(125)

我有一个像下面这样的df。:

我想做以下两个步骤:
1.如果col name的第一个字母与Grade中的值匹配,并且当前值为NA,则将其替换为0。
1.将A1:B2中的值更新为当前值(current value * 100/ colsums())。
我怎样才能让这一切发生?

df <- structure(list(Grade = c("A", "A", "B", "B"), Pass = c("Y", "N", 
"Y", "N"), A1 = c(7, 8, NA, NA), A2 = c(4, 5, NA, NA), A3 = c(9, 
NA, NA, NA), B1 = c(NA, NA, 8, NA), B2 = c(NA, NA, 3, 4)), row.names = c(NA, 
-4L), class = c("tbl_df", "tbl", "data.frame"))
cbjzeqam

cbjzeqam1#

使用dplyr包,我们可以将acrosscase_when一起使用(如果您想使用两个单独的ifelse,请检查我的old edits)。

library(dplyr)

df |> 
  mutate(across(A1:B2, ~case_when(str_extract(cur_column(), "^.") == Grade & is.na(.x) ~ "0 (0%)",
                                  is.na(.x) ~ NA,
                                  .default = paste0(.x, " (", round(.x * 100/(sum(.x, na.rm = T)), digits = 2), "%)"))))

# A tibble: 4 × 7
  Grade Pass  A1         A2         A3       B1       B2        
  <chr> <chr> <chr>      <chr>      <chr>    <chr>    <chr>     
1 A     Y     7 (46.67%) 4 (44.44%) 9 (100%) NA       NA        
2 A     N     8 (53.33%) 5 (55.56%) 0 (0%)   NA       NA        
3 B     Y     NA         NA         NA       8 (100%) 3 (42.86%)
4 B     N     NA         NA         NA       0 (0%)   4 (57.14%)

更新

如果要使用colnames,则需要先pick列。

df %>% 
  mutate(across(A1:B2, ~ifelse(str_extract(colnames(pick(.x)), "^.") == Grade & is.na(.x), 0, .x)), 
         across(A1:B2, ~ifelse(is.na(.x), NA, paste0(.x, " (", round(.x * 100/(sum(.x, na.rm = T)), digits = 2), "%)"))))
fgw7neuy

fgw7neuy2#

具有两个枢轴的备选方案:

library(dplyr)
library(tidyr) # pivot_*
df %>%
  pivot_longer(-c(Grade, Pass)) %>%
  mutate(value = if_else(Grade == substring(name, 1, 1), coalesce(value, 0), value)) %>%
  group_by(name) %>%
  mutate(value = if_else(is.na(value), "", sprintf("%i (%0.02f%%)", value, 100 * value / sum(value, na.rm = TRUE)))) %>%
  pivot_wider()
# # A tibble: 4 × 7
#   Grade Pass  A1           A2           A3            B1            B2          
#   <chr> <chr> <chr>        <chr>        <chr>         <chr>         <chr>       
# 1 A     Y     "7 (46.67%)" "4 (44.44%)" "9 (100.00%)" ""            ""          
# 2 A     N     "8 (53.33%)" "5 (55.56%)" "0 (0.00%)"   ""            ""          
# 3 B     Y     ""           ""           ""            "8 (100.00%)" "3 (42.86%)"
# 4 B     N     ""           ""           ""            "0 (0.00%)"   "4 (57.14%)"

相关问题