根据迭代多行的另一列的值改变新列
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) < 0
和 lag(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))
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) < 0
和 lag(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))