Как использовать отставание/опережение в мутации только с одним начальным значением?

Образец ДФ:

library(tidyverse)

iris <- iris[1:10,]
iris$testlag <- NA
iris[[1,"testlag"]] <- 5

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species testlag
1           5.1         3.5          1.4         0.2  setosa       5
2           4.9         3.0          1.4         0.2  setosa      NA
3           4.7         3.2          1.3         0.2  setosa      NA
4           4.6         3.1          1.5         0.2  setosa      NA
5           5.0         3.6          1.4         0.2  setosa      NA
6           5.4         3.9          1.7         0.4  setosa      NA
7           4.6         3.4          1.4         0.3  setosa      NA
8           5.0         3.4          1.5         0.2  setosa      NA
9           4.4         2.9          1.4         0.2  setosa      NA
10          4.9         3.1          1.5         0.1  setosa      NA

В столбце testlag мне интересно использовать dplyr::lag() для извлечения предыдущего значения и добавления к нему некоторого столбца, например Petal.Length. Поскольку у меня есть только одно начальное значение, каждое последующее вычисление требует, чтобы оно работало итеративно, поэтому я подумал, что что-то вроде mutate будет работать.

Сначала я попытался сделать что-то вроде этого:

iris %>% mutate_at("testlag", ~ lag(.) + Petal.Length)

Но это удалило первое значение и дало действительное значение только для второй строки и NAs для остальных. Интуитивно я знаю, почему он удаляет первое значение, но я думал, что природа mutate позволит ему работать для остальных значений, поэтому я не знаю, как это исправить.

Конечно, используя базу R, я мог бы что-то вроде:

for (idx in 2:nrow(iris)) {
  iris[[idx, "testlag"]] <-
    lag(iris$testlag)[idx] + iris[[idx, "Petal.Length"]]
}

Но я бы предпочел реализовать это в синтаксисе tidyverse.

Изменить: желаемый результат (из моего цикла for)

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species testlag
1           5.1         3.5          1.4         0.2  setosa     5.0
2           4.9         3.0          1.4         0.2  setosa     6.4
3           4.7         3.2          1.3         0.2  setosa     7.7
4           4.6         3.1          1.5         0.2  setosa     9.2
5           5.0         3.6          1.4         0.2  setosa    10.6
6           5.4         3.9          1.7         0.4  setosa    12.3
7           4.6         3.4          1.4         0.3  setosa    13.7
8           5.0         3.4          1.5         0.2  setosa    15.2
9           4.4         2.9          1.4         0.2  setosa    16.6
10          4.9         3.1          1.5         0.1  setosa    18.1

person Nautica    schedule 20.05.2020    source источник
comment
Потому что отставание вызывается только один раз при вводе как 5 NA NA NA NA NA NA NA NA NA и выводе как NA 5 NA NA NA NA NA NA NA NA. Он вызывает лаг не для каждого значения ячейки, а один раз.   -  person Shan R    schedule 20.05.2020


Ответы (2)


Это работает для вас?

library(tidyverse)
library("data.table")

iris <- iris[1:10,]
iris$testlag <- NA
iris[[1,"testlag"]] <- 5

iris %>% mutate (testlag = lag(first(testlag) + cumsum(Petal.Length)))

Результат:

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species testlag
1           5.1         3.5          1.4         0.2  setosa      NA
2           4.9         3.0          1.4         0.2  setosa     6.4
3           4.7         3.2          1.3         0.2  setosa     7.8
4           4.6         3.1          1.5         0.2  setosa     9.1
5           5.0         3.6          1.4         0.2  setosa    10.6
6           5.4         3.9          1.7         0.4  setosa    12.0
7           4.6         3.4          1.4         0.3  setosa    13.7
8           5.0         3.4          1.5         0.2  setosa    15.1
9           4.4         2.9          1.4         0.2  setosa    16.6
10          4.9         3.1          1.5         0.1  setosa    18.0

Поскольку технически длины лепестка N-1 при N = 1 не существует, я оставил первое значение testlag NA. Вам действительно нужно, чтобы это было начальным значением? Если вам нужно, это будет работать:

iris %>% mutate (testlag = lag(first(testlag) + cumsum(Petal.Length), default=first(testlag)))
person Shan R    schedule 20.05.2020

Вам нужна функция tidyr::fill.

library(tidyverse)

iris <- iris[1:10,]
iris$testlag <- NA
iris[[1,"testlag"]] <- 5

iris %>% fill(testlag, .direction = "down")
# Note the default is 'down', but I included here for completeness

Это берет указанный столбец (в данном случае testlag) и копирует любые значения в этом столбце в значения ниже. Это также работает, если у вас есть значение в подмножестве строк: оно копирует значение до тех пор, пока не достигнет нового значения, а затем подбирает его.

Например:

library(tidyverse)

iris <- iris[1:10,]
iris$testlag <- NA
iris[[1,"testlag"]] <- 5
iris[[5,"testlag"]] <- 10
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species testlag
1           5.1         3.5          1.4         0.2  setosa       5
2           4.9         3.0          1.4         0.2  setosa      NA
3           4.7         3.2          1.3         0.2  setosa      NA
4           4.6         3.1          1.5         0.2  setosa      NA
5           5.0         3.6          1.4         0.2  setosa      10
6           5.4         3.9          1.7         0.4  setosa      NA
7           4.6         3.4          1.4         0.3  setosa      NA
8           5.0         3.4          1.5         0.2  setosa      NA
9           4.4         2.9          1.4         0.2  setosa      NA
10          4.9         3.1          1.5         0.1  setosa      NA

Применение этой функции...

iris %>% fill(testlag, .direction = "down")

Дает

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species testlag
1           5.1         3.5          1.4         0.2  setosa       5
2           4.9         3.0          1.4         0.2  setosa       5
3           4.7         3.2          1.3         0.2  setosa       5
4           4.6         3.1          1.5         0.2  setosa       5
5           5.0         3.6          1.4         0.2  setosa      10
6           5.4         3.9          1.7         0.4  setosa      10
7           4.6         3.4          1.4         0.3  setosa      10
8           5.0         3.4          1.5         0.2  setosa      10
9           4.4         2.9          1.4         0.2  setosa      10
10          4.9         3.1          1.5         0.1  setosa      10
person Will Pike    schedule 20.05.2020
comment
Привет, извините, это не то, что я ищу. Я отредактировал желаемый результат. - person Nautica; 20.05.2020