Как выполнить задержку / опережение кадра данных в зависимости от индекса строки - PullRequest
0 голосов
/ 09 июля 2020

Как вы запаздываете / опережаете фрейм данных в зависимости от значения строки - или индекса строки - для достижения следующего результата.

Вот пример набора данных:

id <- c(1,1,1,1,1,1)
a <- c("X1","Mar-20","X2","X3","Apr-20", "X4")

test <- data.frame(id,a)

Желаемый результат:

id|a
1 |Mar-20
1 |Mar-20
1 |Mar-20
1 |Apr-20
1 |Apr-20
1 |Apr-20

Ответы [ 3 ]

2 голосов
/ 09 июля 2020

Использование dplyr и stringr при условии, что шаблон, показанный в вопросе, соответствует всем вашим данным.

library(dplyr)
library(stringr)

test %>% 
  mutate(a = case_when(lead(str_detect(a, "-")) ~ lead(a),
                       lag(str_detect(a, "-")) ~ lag(a),
                       TRUE ~ a))
#>   id      a
#> 1  1 Mar-20
#> 2  1 Mar-20
#> 3  1 Mar-20
#> 4  1 Apr-20
#> 5  1 Apr-20
#> 6  1 Apr-20

Создано пакет REPEX (v0.3.0)

1 голос
/ 09 июля 2020

Я думаю, что это более общее решение этой проблемы.

Вы можете использовать следующую функцию, чтобы указать количество опережений (или запаздываний, если они отрицательны) для каждого значения в столбце, который нужно изменить. В некотором смысле это векторизует опережение / отставание.

lead_lag <- function(lead_lag_this, by_this, default = NA)
{
  diag(sapply(by_this, function(x) if(x == 0) lead_lag_this 
                              else if(x < 0) lead(lead_lag_this, -x, default)
                              else if(x > 0) lag(lead_lag_this, x, default)))
}

Так, например, предположим, что мы добавляем столбец к вашему фрейму данных, который определяет опережение или отставание:

test$leadlag <- c(-1, 0, 1, -1, 0, 1)
test
#>   id      a leadlag
#> 1  1     X1      -1
#> 2  1 Mar-20       0
#> 3  1     X2       1
#> 4  1     X3      -1
#> 5  1 Apr-20       0
#> 6  1     X4       1

Тогда мы можем используйте столбец leadlag для опережения или отставания столбца a следующим образом:

test %>% mutate(new_a = lead_lag(a, leadlag))
#>   id      a leadlag  new_a
#> 1  1     X1      -1 Mar-20
#> 2  1 Mar-20       0 Mar-20
#> 3  1     X2       1 Mar-20
#> 4  1     X3      -1 Apr-20
#> 5  1 Apr-20       0 Apr-20
#> 6  1     X4       1 Apr-20

Конечно, если вы просто хотите создать повторяющийся шаблон, например c(-1, 0, 1), на основе номера строки (без указания столбец leadlag) вы можете сделать

test %>% mutate(new_a = lead_lag(a, (row_number() - 1) %% 3 - 1))
1 голос
/ 09 июля 2020

Вы можете создать группирующую переменную на основе количества строк вашего df и заменить первый и третий экземпляры вторым, т.е.

with(test, ave(a, rep(seq(nrow(test)/3), each = 3), FUN = function(i){i[c(1, 3)] <- i[2]; i}))
#[1] Mar-20 Mar-20 Mar-20 Apr-20 Apr-20 Apr-20
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...