2017-02-20 3 views
0

Я не уверен, что заголовок достаточно точен, чтобы описать мою проблему. У меня есть кадр данных с наборами 1:n из двух групп A и B и возможный статус Calm, Action1 и Action2.R создать новый столбец для набора значений несколькими условиями

triggers <- c("Action1", "Action2") 
    df <- data.frame(Set = c(rep(1, 4), rep(2, 4), rep(1, 4)),                    
        Group = c(rep("A", 4), rep("A", 4), rep("B", 4)),                  
        Status = c(rep("Calm",3), "Action1", rep("Calm",3), 
           "Action2", rep("Calm", 4))) 
Set Group Status 
1 A Calm 
1 A Calm 
1 A Calm 
1 A Action1 
2 A Calm 
2 A Calm 
2 A Calm 
2 A Action2 
1 B Calm 
1 B Calm 
1 B Calm 
1 B Calm 

на основе вектора triggers я хочу, чтобы создать новый столбец, где выполнены следующие условия.

Если в одном наборе (для каждой группы) Action1 или Action2 происходит, чем запись в новый столбец статус Action также для StatusCalm.

Результат в новой колонке должен быть c(rep("Action", 8), rep("Calm", 4)).

Я не мог решить проблему с несколькими условиями в этом фрейме данных. Надеюсь, кто-то может мне помочь и прощает мое не-математическое описание проблемы.

ответ

1

Это должно работать:

df %>% dplyr::group_by(Group, Set) %>% 
    do(mutate(. ,result = ifelse(any(Status %in% triggers), "Action", "Calm"))) 

Source: local data frame [12 x 4] 
Groups: var2, var1 [3] 
    Set Group Status result 
    <dbl> <chr> <chr> <chr> 
1  1  A Calm Action 
2  1  A Calm Action 
3  1  A Calm Action 
4  1  A Action1 Action 
5  2  A Calm Action 
6  2  A Calm Action 
7  2  A Calm Action 
8  2  A Action2 Action 
9  1  B Calm Calm 
10  1  B Calm Calm 
11  1  B Calm Calm 
12  1  B Calm Calm 
+0

Awesome- могли бы вы также обеспечить data.table решение? – Christian

+0

Ахаха, умное использование 'any': D – Aramis7d

+0

@Christian Я не эксперт' data.table'. Мое решение 'data.table' не было бы хорошим. Но если вы не работаете с большим набором данных, 'dplyr' должен хорошо выполнять эту работу. – Alex

0

Учитывая dft как ваш inut dataframe, вы могли бы использовать dplyr и попробовать:

dft %>% 
    group_by(Group, Set) %>% 
    mutate(nc = if_else(Status %in% triggers, 1, 0)) %>% 
    mutate(nc = max(nc)) %>% 
    mutate(nc2 = if_else(nc == 1, "Action", as.character(Status))) %>% 
    select(nc2) 

P.S. вторая и третья команды mutate могут быть объединены в одну.

1

Вот data.table решение по просьбе

library(data.table) 
dt1 <- setDT(df) 
dt1[, result := ifelse(sum(Status %in% triggers) == 0, "Calm", "Action"), by = .(Group, Set)] 

С набором данных при условии, что это примерно в 6,5 раза быстрее, чем с помощью dplyr

+0

В наборе данных есть две переменные группировки. – Alex

+0

@Alex спасибо, исправлено – manotheshark

Смежные вопросы