如何在只有一个初始值的 mutate 中使用 laglead?

问题描述 投票:1回答:2

示例df。

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)

但这样就把第一个值去掉了 只给第二行一个有效的值 NA的其余部分。直观上我知道为什么要去掉第一个值,但我认为在本质上 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
r dplyr tidyverse lag mutate
2个回答
3
投票

这对你有用吗?

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)))

0
投票

你要找的函数是 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

0
投票

我不太清楚你在找什么,但这个方向对吗?

mutate(iris, testlag = Petal.Length + lag(Petal.Length, default = 0))

这样,testlag列是当前行的petal.legnth和之前行的petal.legnth之和。

© www.soinside.com 2019 - 2024. All rights reserved.