如何在R中基于后续行值跨列校验条件并生成新列?
在R中为tibble添加滞后判断列的实现方法
原始数据与需求
首先,用户创建的tibble数据框代码如下:
library(tidyverse) df = tibble(Date = seq(as.Date("2022/1/1"), by = "day", length.out = 5), y = c(-0.0169518377693283,-0.0272755133312903,0.166639806607574,0.0786074354127284,-0.0689321729520651), a = rep(-0.1377444258,5), b = rep(0.137742579)) options(pillar.sigfig=7)
数据框展示:
# A tibble: 5 x 4 Date y a b <date> <dbl> <dbl> <dbl> 1 2022-01-01 -0.01695184 -0.1377444 0.1377426 2 2022-01-02 -0.02727551 -0.1377444 0.1377426 3 2022-01-03 0.1666398 -0.1377444 0.1377426 4 2022-01-04 0.07860744 -0.1377444 0.1377426 5 2022-01-05 -0.06893217 -0.1377444 0.1377426
需求:添加两列
checkdown:判断当前行的a值是否小于两天后的y值checkup:判断当前行的b值是否大于两天后的y值
最后两行因无两天后的数据,对应列留空(实际为NA)。
最优实现方法(tidyverse)
使用dplyr中的lead()函数直接获取后续第2行的y值,结合逻辑判断即可完成,代码简洁高效:
df_result <- df %>% mutate( checkdown = a < lead(y, n = 2), checkup = b > lead(y, n = 2) ) # 查看结果 df_result
运行后得到的结果与预期一致:
# A tibble: 5 x 6 Date y a b checkdown checkup <date> <dbl> <dbl> <dbl> <lgl> <lgl> 1 2022-01-01 -0.01695184 -0.1377444 0.1377426 TRUE FALSE 2 2022-01-02 -0.02727551 -0.1377444 0.1377426 TRUE TRUE 3 2022-01-03 0.1666398 -0.1377444 0.1377426 TRUE TRUE 4 2022-01-04 0.07860744 -0.1377444 0.1377426 NA NA 5 2022-01-05 -0.06893217 -0.1377444 0.1377426 NA NA
rollapply是否适用?
rollapply(来自zoo包)确实可以实现该需求,但属于“杀鸡用牛刀”——因为lead()函数已经完美匹配“获取后续n行数据”的场景,代码更简洁直观。
如果一定要用rollapply,示例代码如下:
library(zoo) df_rollapply <- df %>% mutate( checkdown = rollapply(y, width = list(c(3)), function(x) a < x, fill = NA, align = "left"), checkup = rollapply(y, width = list(c(3)), function(x) b > x, fill = NA, align = "left") )
这里通过指定width = list(c(3))和align = "left",实现取当前行之后第2个位置的y值,最终效果与lead()方法一致,但代码复杂度更高。
内容的提问来源于stack exchange,提问作者Homer Jay Simpson
相关产品推荐
相关产品推荐

