2017-02-09 8 views
1

У меня есть следующий кадр данных -Итерационная замена значения с лагом значений с использованием dplyr

x <- c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) 
y <- c(0,0,0,1,0,-1,0,-1,0,1,0,-1,0,1,0,0,0) 
data <- data.frame(x,y) 

, и я хотел бы создать тип индикатора импульса. Эффективно, если y отличен от нуля, x принимает значение y, а если y равно 0, x принимает значение запаздывающего значения x. По сути, я заменяю значение x по строкам. Делать это в цикле просто -

for (i in 1:nrow(data)) { 
    data$x[i] <- 
    ifelse(data$y[i] == 1, 1, ifelse(data$y[i] == -1, -1, data$x[i-1]))} 

Дай мне этот вывод (то, что я ищу)

x y 
1 NA 0 
2 NA 0 
3 NA 0 
4 1 1 
5 1 0 
6 -1 -1 
7 -1 0 
8 -1 -1 
9 -1 0 
10 1 1 
11 1 0 
12 -1 -1 
13 -1 0 
14 1 1 
15 1 0 
16 1 0 
17 1 0 

Однако, на самом деле больших массивов данных, этот цикл является крайне неэффективным. Я хотел бы реализовать это в dplyr, однако самое лучшее решение, которое я смог придумать не сделать трюк

data2 <- data.frame(x,y) 

data2 <- 
    data2 %>% 
    mutate(x = ifelse(y == 1, 1, ifelse(y == -1, 0, Lag(x)))) 

которые возвращают этот

x y 
1 NA 0 
2 1 0 
3 1 0 
4 1 1 
5 1 0 
6 0 -1 
7 1 0 
8 0 -1 
9 1 0 
10 1 1 
11 1 0 
12 0 -1 
13 1 0 
14 1 1 
15 1 0 
16 1 0 
17 1 0 

Я думаю, что так, как я В настоящее время я пытаюсь сделать это в dplyr, не контролируя итеративный характер того, что я хочу сделать, а именно замену x, когда я перемещаюсь по строкам. У кого-нибудь есть идеи относительно того, как я мог бы это сделать через dplyr?

+3

Вы можете получить показатели последнего Неправительственный -zero "y" с 'cummax (as.logical (y) * seq_along (y))'. Тогда, заменив нули на 'NA' и подмножество' y', должен дать результат. –

ответ

1

Одним из вариантов является замена 0 с NA, а затем сделать вперед заливку:

library(dplyr); library(tidyr) 
data %>% mutate(x = na_if(y, 0)) %>% fill(x) 

# x y 
#1 NA 0 
#2 NA 0 
#3 NA 0 
#4 1 1 
#5 1 0 
#6 -1 -1 
#7 -1 0 
#8 -1 -1 
#9 -1 0 
#10 1 1 
#11 1 0 
#12 -1 -1 
#13 -1 0 
#14 1 1 
#15 1 0 
#16 1 0 
#17 1 0 
+0

@Psidon - спасибо за это; делает работу элегантно. –

0

Вот еще один вариант с использованием na.locf из zoo

library(zoo) 
data$x <- with(data, na.locf(y*(NA^!y), na.rm=FALSE)) 

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

  • Нет связанных вопросов^_^