是否可以在 dplyr :: lag 函数中将列值用作 n ?
可复制的示例:
DF <- data.frame(
V = runif(1000, min=-100, max=100),
nlag = as.integer(runif(1000, min=1, max=10))
) %>%
mutate(Vlag = lag(V, n = nlag))
我收到此错误:
错误:评估错误:
n
必须是非负整数标量,而不是长度1000的整数。
还有其他选择吗?
更新:
我们如何解决小组内部的相同问题?
可复制的示例:
DF <- data.frame(
V = runif(1000, min=-100, max=100),
nlag = as.integer(runif(1000, min=1, max=10)),
type = sample(1:4, replace=TRUE)
) %>%
group_by(type) %>%
mutate(Vlag = lag(V, n = nlag))
答案 0 :(得分:6)
?lag
上的文档说
n
长度为1的正整数,给出领先或落后的位置数
因此,不能给出大于length = 1
的数字。
但是,我们可以通过将当前行索引减去相应的V
值来生成索引来获得nlag
值,然后使用该索引来获取滞后的V
值。
df$lag_value <- sapply(seq_along(df$nlag), function(x) {
indx = x - df$nlag[x]
if(indx > 0)
df$V[indx]
else
NA
})
df
# V nlag lag_value
#1 51.30453 6 NA
#2 -66.33709 4 NA
#3 95.45096 9 NA
#4 44.54434 3 51.30453
#5 62.00180 3 -66.33709
#6 -18.43012 4 -66.33709
更新
如果我们要按组进行操作,可以按type
列将其拆分并应用相同的操作。
df$lag_value <- unlist(lapply(split(df, df$type), function(x)
sapply(seq_along(x$nlag), function(y) {
indx = y - x$nlag[y]
if(indx > 0)
x$V[indx]
else
NA
})))
数据
df <- head(DF)
答案 1 :(得分:3)
nlag
的长度必须为1,尝试执行以下操作:
DF <- data.frame(
V = runif(1000, min=-100, max=100),
nlag = as.integer(runif(1000, min=1, max=10))
) %>% mutate(Vlag = V[if_else((row_number() - nlag) < 1, as.integer(NA), row_number() - nlag)])
V nlag Vlag
1 -6.72598341 4 NA
2 -84.67472238 2 NA
3 -4.98048104 7 NA
4 2.64957272 4 NA
5 82.16284532 4 -6.72598341
6 28.93483448 9 NA
7 88.16730371 3 2.64957272
8 42.31721302 7 -6.72598341
9 -38.12659876 1 42.31721302
10 74.62628153 3 88.16730371
...
答案 2 :(得分:0)
另一个选择是使用purrr
软件包。 map2_dbl
将两个长度相同的矢量(或列表)作为输入,并同时对其进行迭代。然后返回double
。在map
调用内,用指定的`nlag计算V的lag
,然后仅返回当前行。
library(dplyr)
library(purrr)
DF %>%
mutate(Vlag = map2_dbl(nlag, row_number(), ~ lag(V, n = .x)[.y]))
# A tibble: 20 x 3
# V nlag Vlag
# <dbl> <int> <dbl>
# 1 83.0 9 NA
# 2 87.4 2 NA
# 3 -42.8 9 NA
# 4 66.1 9 NA
# 5 28.3 1 66.1
# 6 3.82 5 83.0
# 7 47.3 4 -42.8
# 8 -73.1 9 NA
# 9 31.4 5 66.1
# 10 41.0 8 87.4
# ...
数据
以随机数为例时,应指定一个种子。同样在这种情况下,较少的行数足以显示问题。
set.seed(42)
DF <- tibble(V = runif(20, min=-100, max=100),
nlag = as.integer(runif(20, min=1, max=10)))
答案 3 :(得分:0)
我认为这比当前答案还干净:
DF %>%
group_by(ID, nlag) %>%
mutate(Vlag = dplyr::lag(V, n = nlag[1])) %>%
ungroup()
由于已将nlag
分组,因此所有索引都相同,因此可以使第一个工作正常。