首页 > 解决方案 > 移动时间序列(将所有值降至某个阈值以下)

问题描述

我有以下data.frame:

A <- c(10,20,30,90,180,400)
B <- c(5, 25, 50, 401, 490, 500)
C <- c(200, 300, 480, 890, 1100, 1200)
df <- data.frame(A, B, C)
df

看起来像这样:

    A   B    C
1  10   5  200
2  20  25  300
3  30  50  480
4  90 401  890
5 180 490 1100
6 400 500 1200

现在,我想移动时间序列 A、B 和 C,使第一个值高于某个阈值(例如 400)。所以结果应该是这样的:

     A    B    C
1  400  401  480
2   NA  490  890
3   NA  500 1100
4   NA   NA 1200

标签: rdataframetime-seriestidyversetidyr

解决方案


我们可以使用sapply循环列和过滤高于阈值的值。然后我们可以使用cbind.fillfromrowr来组合它们

setNames(do.call(rowr::cbind.fill, c(sapply(df, function(x) 
                 x[x >= 400]), fill = NA)), names(df))

#    A   B    C
#1 400 401  480
#2  NA 490  890
#3  NA 500 1100
#4  NA  NA 1200

一个tidyverse选项是:

library(tidyverse)

map(df, ~.x[.x >= 400]) %>%
    enframe() %>%
    unnest(value) %>%
    group_by(name) %>%
    mutate(row = row_number()) %>%
    pivot_wider() %>%
    select(-row)

推荐阅读