выполнение математических функций через фрейм данных - PullRequest
1 голос
/ 21 января 2020

У меня есть следующий df. Я хотел бы сгруппировать по ID и сделать Fy = (Fyb + Fya) / 2 для каждого столбца, который заканчивается диаграммами. Если любое из двух значений равно NA, выход NA будет иметь значение.

DATA

df <- structure(list(ID = c("51-07519", "51-07519", "51-07522", "51-07522", 
"51-07525", "51-07525"), name = c("Fya", "Fyb", "Fya", "Fyb", 
"Fya", "Fyb"), serology_charts = c("0", "0", "0", "0", NA, NA
), antibodies_charts = c(NA_character_, NA_character_, NA_character_, 
NA_character_, NA_character_, NA_character_), bioarray_charts = c(NA, 
NA, "0", "0", NA, NA), others_charts = c(NA_character_, NA_character_, 
NA_character_, NA_character_, NA_character_, NA_character_)), row.names = c(NA, 
-6L), class = c("tbl_df", "tbl", "data.frame"))
  ID       name  serology_charts antibodies_charts bioarray_charts others_charts
  <chr>    <chr> <chr>           <chr>             <chr>           <chr>        
1 51-07519 Fya   0               NA                NA              NA           
2 51-07519 Fyb   0               NA                NA              NA           
3 51-07522 Fya   0               NA                0               NA           
4 51-07522 Fyb   0               NA                0               NA           
5 51-07525 Fya   NA              NA                NA              NA           
6 51-07525 Fyb   NA              NA                NA              NA

DESIRED ВЫХОД

   ID       name  serology_charts antibodies_charts bioarray_charts others_charts
  <chr>    <chr> <chr>           <chr>             <chr>           <chr>        
1 51-07519 Fy   0               NA                NA              NA           
2 51-07522 Fy   0               NA                0               NA           
3 51-07525 Fy   NA              NA                NA              NA           

1 Ответ

1 голос
/ 21 января 2020

Мы можем сначала преобразовать типы столбцов с помощью type.convert, затем сделать group_by summarise_at (и при необходимости преобразовать столбцы обратно в character - не понятно, почему столбцы являются символьными)

library(dplyr)
df %>%
   type.convert(as.is = TRUE) %>% 
   group_by(ID) %>% 
   summarise_at(vars(ends_with('charts')),
         ~ if(any(is.na(.))) NA_real_ else sum(., na.rm = TRUE)) %>%
   mutate(name = 'Fy') %>%
   mutate_at(vars(ends_with('charts')), as.character) %>%
   select(names(df))
# A tibble: 3 x 6
#  ID       name  serology_charts antibodies_charts bioarray_charts others_charts
#  <chr>    <chr> <chr>           <chr>             <chr>           <chr>        
#1 51-07519 Fy    0               <NA>              <NA>            <NA>         
#2 51-07522 Fy    0               <NA>              0               <NA>         
#3 51-07525 Fy    <NA>            <NA>              <NA>            <NA>         

Если нам нужно передать другую функцию, основанную на значении в 'name'

df %>%
    type.convert(as.is = TRUE) %>%
    group_by(ID) %>%
     summarise_at(vars(ends_with('charts')),
         ~ if(any(is.na(.))) NA_real_ else
            (.[name == "Fyb"]+1)*(.[name == "Fya"])/2) 
...