根据迭代多行的另一列的值改变新列

Mutate new column conditioned on values of another column iterating over multiple rows

library(dplyr)

df <- tibble(year = 1951:2000,
             val = rnorm(50))

假设上面的 df,我想向 tibble 添加一个额外的列(比如 cond),使其值取决于列 val 的前两行。

换句话说,if (val[i-1] & val[i-2]) < 0 ,将值1赋给cond[i],否则为零 .

您可以使用 lag,它采用第二个参数告诉函数您希望将矢量滞后多少步。因此,如果 lag(val) < 0lag(val, 2) < 0 满足您的标准。我已将其包装在 tidyr::replace_na 中,假设您希望在未定义标准的前两行中使用 0。

set.seed(3)

df <- tibble(year = 1951:2000, val = rnorm(50))

df %>% mutate(cond = tidyr::replace_na(as.numeric(lag(val) < 0 & lag(val, 2) < 0), 0))

#> # A tibble: 50 x 3
#>     year     val  cond
#>    <int>   <dbl> <dbl>
#>  1  1951 -0.962      0
#>  2  1952 -0.293      0
#>  3  1953  0.259      1
#>  4  1954 -1.15       0
#>  5  1955  0.196      0
#>  6  1956  0.0301     0
#>  7  1957  0.0854     0
#>  8  1958  1.12       0
#>  9  1959 -1.22       0
#> 10  1960  1.27       0
#> # ... with 40 more rows

根据您的描述,有一个 for 循环。我不确定如何处理前两个值,因此我在 df$val 中包含了相同的值。了解 R 中循环的解决方案,但比 Allan Cameron 提供的出色解决方案更冗长:

library(dplyr)

df$cond = 1:nrow(df)

val <- df$val

for (i in seq_along(val)) {
    if (i == 1 | i == 2) 
        df$cond[i] <- val[i]
    else if (val[i -1] < 0 & val[i -2] < 0)
        df$cond[i] <- 1
    else 
        df$cond[i] <- 0
}

输出

> df
# A tibble: 50 × 3
    year     val   cond
   <int>   <dbl>  <dbl>
 1  1951 -0.560  -0.560
 2  1952 -0.230  -0.230
 3  1953  1.56    1    
 4  1954  0.0705  0    
 5  1955  0.129   0    
 6  1956  1.72    0    
 7  1957  0.461   0    
 8  1958 -1.27    0    
 9  1959 -0.687   0    
10  1960 -0.446   1    
# … with 40 more rows

数据

set.seed(123)

df <- tibble(year = 1951:2000, val = rnorm(50))