случай, когда с несколькими условиями в dplyr R

#r #dplyr #datatable #tidyverse

Вопрос:

У меня есть данные.фрейм, который выглядит так

 df <-data.frame(Day=c(0,0,0,1,1,1),type=c("tr1","tr2","ctrl","tr1","tr2","ctrl"),
                mean=c(0.211,0203,0.199,0.119,0.001,0.254), 
                sd=c(0.07,0.141,0.096, 0.0848, 0.0006, 0.0474))

  Day type    mean     sd
1   0  tr1   0.211 0.0700
2   0  tr2 203.000 0.1410
3   0 ctrl   0.199 0.0960
4   1  tr1   0.119 0.0848
5   1  tr2   0.001 0.0006
6   1 ctrl   0.254 0.0474

 

Сначала я хочу сгруппировать свой кадр данных по дню, он же group_by(День).
Когда в каждой группе сумма(среднее значение sd) каждого типа (tr1, tr2) больше, чем
разница(среднее значение — sd) элемента управления (ctrl), я хочу в новом столбце (new.col) присвоить значение ~да, а если нет, я хочу присвоить значение ~нет.

Например, я хочу, чтобы мои данные выглядели как-то так. Это не должно выглядеть так

   Day type    mean     sd new.col
1   0  tr1   0.211 0.0700  yes
2   0  tr2 203.000 0.1410  yes
3   0 ctrl   0.199 0.0960  NA
4   1  tr1   0.119 0.0848  NO
5   1  tr2   0.001 0.0006  N0
6   1 ctrl   0.254 0.0474  NA
 

Комментарии:

1. Вы правы @akrun. Я все исправлю как можно скорее. Мне нужно поставить «НЕТ». спасибо вам 🙂

2. Привет, DPH, я думаю, что это должно быть НЕТ, так как 0,119 0,0848 = 0,2038

Ответ №1:

После группировки по ‘День’, одним из вариантов является подмножеством в ‘Значит’, ‘СД’ значений, где » тип » Не ( != ) или «Ctrl», добавить ( ) столбцов, получить sum , проверить, если он больше ( > ), чем соответствующие значения добавлены в ‘Значит’, ‘СД’ где ‘тип’ в ‘сочетание клавиш Ctrl’. Преобразуйте логический индекс в числовой, добавив 1, используйте его для замены вектором значений ( c("NO", "Yes") ). Наконец, измените строки, в которых «тип» — это «ctrl», на NA с case_when

 library(dplyr)
df %>% 
    group_by(Day) %>% 
    mutate(new.col = case_when(type == "ctrl" ~ NA_character_, 
     TRUE ~ c("NO", "Yes")[1   (sum(mean[type != "ctrl"]   
      sd[type != "ctrl" ]) >  (mean[type == 'ctrl'] - sd[type == 'ctrl']))])) %>%
    ungroup
 

-выход

 # A tibble: 6 x 5
    Day type     mean     sd new.col
  <dbl> <chr>   <dbl>  <dbl> <chr>  
1     0 tr1     0.211 0.07   Yes    
2     0 tr2   203     0.141  Yes    
3     0 ctrl    0.199 0.096  <NA>   
4     1 tr1     0.119 0.0848 NO     
5     1 tr2     0.001 0.0006 NO     
6     1 ctrl    0.254 0.0474 <NA>   
 

Комментарии:

1. У меня есть 181 условие для столбца, которые затрудняют использование case_when. Я написал эти условия в файле с двумя столбцами(условие,группа), можно ли сделать это автоматически, не добавляя 181 строку в мой код?

2. @Masoud Вы можете использовать соединение с ключевым столбцом, если это так. Это было бы более эффективно, чем case_when

Ответ №2:

одной из альтернатив с dplyr может быть следующая:

 library(dplyr)

df %>% 
  dplyr::left_join(df %>% dplyr::filter(type == "ctrl"), by = "Day", suffix = c("_t", "_c")) %>%
  dplyr::group_by(Day, type_t) %>%
  dplyr::mutate(new.col = case_when(type_t == "ctrl" ~ NA_character_,
                                   sum(mean_t   sd_t) > (mean(mean_c -sd_c)) ~ "yes",
                                   TRUE ~ "no")) %>%
  dplyr::ungroup() %>%
  dplyr::select(Day, type = type_t, mean = mean_t, sd = sd_t, new.col)

# A tibble: 6 x 5
    Day type     mean     sd new.col
  <dbl> <chr>   <dbl>  <dbl> <chr>  
1     0 tr1     0.211 0.07   yes    
2     0 tr2   203     0.141  yes    
3     0 ctrl    0.199 0.096  NA     
4     1 tr1     0.119 0.0848 no     
5     1 tr2     0.001 0.0006 no     
6     1 ctrl    0.254 0.0474 NA