2016-12-10 5 views
1

У меня есть следующие данные:Объединение данных из строк на основе условий или последовательностей

Data <- data.frame(Project=c(123,123,123,123,123,123,124,124,124,124,124,125,125,125,126,126), 
        Value=c(1,4,7,3,8,9,8,3,2,5,6,2,2,1,8,3), 
        OldValue=c("","Open","In Progress","Complete","Open","In Progress","Complete","Open","In Progress","System Declined","In Progress","","Open","In Progress","In Progress",""), 
        NewValue=c("Open","In Progress","Complete","Open","In Progress","Complete","Open","In Progress","System Declined","In Progress","Complete","Open","In Progress","Complete","","In Progress")) 

Data$First <- ifelse(((Data$OldValue==""|Data$OldValue=="Complete"|Data$OldValue=="System Declined")&Data$NewValue=="Open"),Data$Value,NA) 
Data$Second <- ifelse(((Data$OldValue=="Open"|Data$OldValue=="Complete"|Data$OldValue=="System Declined")&Data$NewValue=="In Progress"),Data$Value,NA) 
Data$Third <- ifelse(((Data$NewValue=="Complete"|Data$NewValue=="System Declined")&Data$OldValue=="In Progress"),Data$Value,NA) 

enter image description here

для каждого уникального проекта ID, я хочу, чтобы объединить первое, второе & Третьи значения в одну строку , Я только хочу, чтобы это сделать, если значения в столбце NEWVALUE следуют либо из последовательностей ниже:

Open, In Progress, Complete или Open, In Progress, система Отклонено

Так Проект 123 будет иметь два ряды данных, а также проекты 124 & 125. Строки 10 и 11 будут исключены, так как они не соответствовали вышеприведенной последовательности.

Что может быть проще всего для этого?

ответ

0

решение с использованием dplyr:

library(dplyr) 
Data %>% group_by(Project) %>% 
    mutate(
     fl = as.numeric(NewValue), 
     flag = paste(lag(fl, 2, default = 0), 
        lag(fl, 1, default = 0), 
        fl, sep = ''), 
     merge = paste(lag(Value, 2, default = 0), 
         lag(Value, 1, default = 0), 
         Value, sep = ',') 
    ) %>% 
    filter(flag == '321' | flag == '324') %>% 
    select(Project, merge) 

# Project merge 
#  <dbl> <chr> 
# 1  123 1,4,7 
# 2  123 3,8,9 
# 3  124 8,3,2 
# 4  125 2,2,1 
0

Это будет один из способов достижения этой цели. Я хотел создать последовательность чисел, которые могут представлять два указанных вами шаблона (т. Е. Open-In Progress-Complete и Open-In Progress-System Declined). По этой причине я свалил уровни факторов на три, используя fct_collapse(). Затем я преобразовал новые уровни факторов в числовые. Затем я хотел создать подгруппу в каждом Project, который я сделал во втором mutate(). Следующей задачей было изменить порядок элементов в First, Second и Third. Вы хотели иметь номера в одной строке. Поэтому я использовал sort(). Было одно условие для применения этой операции: identical(check[1:3], as.numeric(1:3)). Если у вас есть один из двух шаблонов, вы должны ожидать последовательность из 1, 2, 3 в check. Вы используете эту логическую проверку для каждой группы. Пока выполняется это логическое условие, sort() применяется к трем столбцам в каждой группе, определяемой Project и group. Наконец, я удалил check и group, которые я использовал для всей этой операции.

library(dplyr) 
library(forcats) 

Data %>% 
mutate(check = as.numeric(
        as.character(fct_collapse(NewValue, 
              `1` = "Open", 
              `2` = "In Progress", 
              `3` = c("Complete", "System Declined"))))) %>% 
group_by(Project) %>% 
mutate(group = cumsum(c(TRUE, diff(check) != 1))) %>% 
group_by(Project, group) %>% 
mutate_at(vars(First:Third), 
      funs(if(identical(check[1:3], as.numeric(1:3))){ 
       sort(., na.last = TRUE)} else{.} 
     )) %>% 
select(-check, -group) 

# group Project Value  OldValue  NewValue First Second Third 
# <int> <dbl> <dbl>   <fctr>   <fctr> <dbl> <dbl> <dbl> 
#1  1  123  1       Open  1  4  7 
#2  1  123  4   Open  In Progress NA  NA NA 
#3  1  123  7  In Progress  Complete NA  NA NA 
#4  2  123  3  Complete   Open  3  8  9 
#5  2  123  8   Open  In Progress NA  NA NA 
#6  2  123  9  In Progress  Complete NA  NA NA 
#7  1  124  8  Complete   Open  8  3  2 
#8  1  124  3   Open  In Progress NA  NA NA 
#9  1  124  2  In Progress System Declined NA  NA NA 
#10  2  124  5 System Declined  In Progress NA  5 NA 
#11  2  124  6  In Progress  Complete NA  NA  6 
#12  1  125  2       Open  2  2  1 
#13  1  125  2   Open  In Progress NA  NA NA 
#14  1  125  1  In Progress  Complete NA  NA NA 
+0

Спасибо за помощь, но я столкнулся с проблемой при применении этого к более крупному набору данных. Я понял, что есть несколько случаев, когда отношения OldValue, NewValue не рассматриваются в моей исходной логике (Data $ First, Data $ Second, Data $ Third). Я обновил исходный код в вопросе, чтобы отразить точный экземпляр, о котором я говорю. Когда я повторно запускаю код с новыми данными, я получаю сообщение об ошибке «R Session Aborted. R столкнулся с фатальной ошибкой. Сессия была прервана». – Dfeld

+0

@Dfeld Ваш размер? Я посмотрю ваш вопрос позже, так как я должен сейчас подготовиться к своей работе. Надеюсь, вы не возражаете. – jazzurro

+0

Есть около 10 000 строк, импортированных из файла csv. Я тестировал его на нескольких тысячах строк успешно, но экземпляры, подобные тому, которые я объяснял выше, и добавленные в код, вызывают R сбой. Еще раз спасибо джаззурро. No rush – Dfeld