使用paste0进行mutate across以更新多个列的值

ss2ws0br  于 2023-03-27  发布在  其他
关注(0)|答案(3)|浏览(114)

我有一个像下面这样的df。我想用col名称的第一个字母更新none NA值,然后将A1:B5粘贴在一起。这是一个聪明的方法吗?也许是像mutate across这样的方法?

df<-structure(list(ID = c("Tom", "Jerry", "Kate"), A1 = c(NA, 78, 
NA), A2 = c(NA, NA, NA), A3 = c(NA, NA, 25), A4 = c(96, NA, NA
), A5 = c(NA, NA, NA), B1 = c(NA, NA, 74), B2 = c(NA, NA, NA), 
    B3 = c(NA, NA, NA), B4 = c(98, NA, NA), B5 = c(NA, NA, NA
    )), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"
))
b1uwtaje

b1uwtaje1#

df %>% 
  mutate(across(A1:B5, 
     ~ ifelse(!is.na(.x),paste0(str_sub(cur_column(),1,1), ":", .x), .x))) %>%
  unite(Summary, -ID, sep = ';', na.rm = TRUE, remove = FALSE)

# A tibble: 3 × 12
  ID    Summary   A1    A2    A3    A4    A5    B1    B2    B3    B4    B5   
  <chr> <chr>     <chr> <lgl> <chr> <chr> <lgl> <chr> <lgl> <lgl> <chr> <lgl>
1 Tom   A:96;B:98 NA    NA    NA    A:96  NA    NA    NA    NA    B:98  NA   
2 Jerry A:78      A:78  NA    NA    NA    NA    NA    NA    NA    NA    NA   
3 Kate  A:25;B:74 NA    NA    A:25  NA    NA    B:74  NA    NA    NA    NA
lnxxn5zx

lnxxn5zx2#

你可以试试Base R的解决方案:

na.omit(cbind(df[1], stack(df, -1)))|>
   transform(Summary = paste0(substr(ind, 1, 1), values))|>
   aggregate(Summary~ID, x = _, paste, collapse = ';') |>
   merge(df, sort = FALSE)

     ID Summary A1 A2 A3 A4 A5 B1 B2 B3 B4 B5
1 Jerry     A78 78 NA NA NA NA NA NA NA NA NA
2  Kate A25;B74 NA NA 25 NA NA 74 NA NA NA NA
3   Tom A96;B98 NA NA NA 96 NA NA NA NA 98 NA
vhmi4jdf

vhmi4jdf3#

这变成了一个很长的管道。注意,在paste中使用collapse=!这是汇总多行的技巧。

library(tidyverse)
df %>% 
  pivot_longer(-ID) %>% 
  drop_na("value") %>% 
  mutate(value=paste0(str_sub(name,1,1), ": ", value)) %>% 
  group_by(ID) %>% 
  summarise(Summary=paste(value, collapse = ", ")) # %>%    
  # merge(df, sort = FALSE) # uncomment to include original columns

#  ID    Summary     
#1 Jerry A: 78       
#2 Kate  A: 25, B: 74
#3 Tom   A: 96, B: 98

如果你不想包含前导字母,有一个简单的unite方法。更改remove=T以保留现有的列。

df %>% unite("Summary", A1:B5, na.rm = T, sep = ", ", remove=F)
#  ID    Summary
#1 Tom   96, 98 
#2 Jerry 78     
#3 Kate  25, 74

相关问题