2015-04-11 2 views
3

Мне нужно заполнить строки NA предыдущим значением строки, но только до тех пор, пока критерии не будут изменены. В качестве простого примера для дней недели, питание и цены:R заполнить NA с предыдущим значением строки с условием

Day = c("Mon", "Tues", "Wed", "Thus", "Fri", "Sat","Sun","Mon", "Tues", 
     "Wed", "Thus", "Fri", "Sat","Sun") 
Meal = c("B","B","B","B","B","D","D","D","D","L","L", "L","L","L") 
Price = c(NA, 20, NA,NA,NA,NA,NA,15,NA,NA,10,10,NA,10) 
df = data.frame(Meal,Day ,Price) 
df 
    Meal Day Price 
1  B Mon NA 
2  B Tues 20 
3  B Wed NA 
4  B Thus NA 
5  B Fri NA 
6  D Sat NA 
7  D Sun NA 
8  D Mon 15 
9  D Tues NA 
10 L Wed NA 
11 L Thus 10 
12 L Fri 10 
13 L Sat NA 
14 L Sun 10 

мне нужно заполнить в НС с предыдущим, но только для одного типа еды, в течение недели.

Я попытался

 na.locf(df, fromLast = TRUE) 
    Meal Day Price 
1  B Mon 20 
2  B Tues 20 
3  B Wed 15 
4  B Thus 15 
5  B Fri 15 
6  D Sat 15 
7  D Sun 15 
8  D Mon 15 
9  D Tues 10 
10 L Wed 10 
11 L Thus 10 
12 L Fri 10 
13 L Sat 10 
14 L Sun 10 

что неправильно, как перекрывается тип еды. Данные должны выглядеть следующим образом:

Meal Day Price 
1  B Mon 20 
2  B Tues 20 
3  B Wed 20 
4  B Thus 20 
5  B Fri 20 
6  D Sat 15 
7  D Sun 15 
8  D Mon 15 
9  D Tues 15 
10 L Wed 10 
11 L Thus 10 
12 L Fri 10 
13 L Sat 10 
14 L Sun 10 

Большое спасибо

+0

Что делать, если есть дубликаты для «Day 'для каждой «еды», т. е. несколько недель на «питание»? Состояние сбрасывается на «Mon» или «Sun»? – akrun

ответ

5

Другой вариант использования data.table

library(data.table) 
library(xts) 

dt <- data.table(df) 

dt[, Price := na.locf(Price, fromLast = TRUE), by = Meal] 
+0

Я получаю предупреждение с этой опцией, хотя это работает – akrun

+0

Я попробовал это решение, а также получил предупреждения, но результат выглядит нормально. – lchester

+0

@akrun & @ichester - Да, я тоже получил это предупреждение, не знаю, почему быть честным ... akrun - Я получил аналогичное предупреждение из вашего предыдущего ответа data.table(). – Chase

1

Вы могли бы попробовать

library(zoo) 
library(dplyr) 
df %>% 
    group_by(Meal) %>% 
    mutate(Price= ifelse(any(!is.na(Price)), na.locf(na.locf(Price, 
        fromLast=TRUE, na.rm=FALSE)), NA_real_)) 
#  Meal Day Price 
#1  B Mon 20 
#2  B Tues 20 
#3  B Wed 20 
#4  B Thus 20 
#5  B Fri 20 
#6  D Sat 15 
#7  D Sun 15 
#8  D Mon 15 
#9  D Tues 15 
#10 L Wed 10 
#11 L Thus 10 
#12 L Fri 10 
#13 L Sat 10 
#14 L Sun 10 
+0

Я тестировал это решение на образцах данных, и он отлично работает. Если я использовал его по моим данным (7 миллионов строк), это ошибки с: Ошибка: несовместимый размер (0), ожидающий 39712 (размер группы) или 1 – lchester

+0

Возможно, 'df%>% group_by (Meal)%>% mutate (Price = ifelse (any (! is.na (Price)), na.locf (na.locf (Цена, fromLast = TRUE, na.rm = FALSE)), NA_real _)) ' – akrun

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