dplyr滞后,列值为n

时间:2018-08-28 08:08:40

标签: r dplyr

是否可以在 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))

4 个答案:

答案 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分组,因此所有索引都相同,因此可以使第一个工作正常。