Как дублировать верхнее значение наблюдения в нижние obs на основе условия?

#r

#r

Вопрос:

Давайте рассмотрим, что в наборе данных есть три переменные (A, B и c), и теперь мне нужно создать переменную D на основе определенных условий. Если B имеет Y, то то же значение C должно сохраняться в переменной D до появления следующего Y.

 A B  C   D (required output)
1 Y 10   10
2   11   10
3   2    10
4   5    10
5   8    10
6 Y 2    2
7   3    2
8   45   2
9 Y 1    1
10  0    1
  

Можете ли вы, пожалуйста, помочь мне получить требуемый вывод в R

Ответ №1:

Вот базовый параметр R, использующий rep rle cumsum

 within(df,D <- rep(C[B=="Y"],rle(cumsum(B=="Y"))$lengths))
  

что дает

     A B  C  D
1   1 Y 10 10
2   2   11 10
3   3    2 10
4   4    5 10
5   5    8 10
6   6 Y  2  2
7   7    3  2
8   8   45  2
9   9 Y  1  1
10 10    0  1
  

Данные

 > dput(df)
structure(list(A = 1:10, B = c("Y", "", "", "", "", "Y", "", 
"", "Y", ""), C = c(10L, 11L, 2L, 5L, 8L, 2L, 3L, 45L, 1L, 0L
)), class = "data.frame", row.names = c(NA, -10L))
  

Ответ №2:

Мы также можем использовать индекс, сгенерированный cumsum , чтобы заменить подмножество значений в ‘C’ для создания столбца ‘D’

 library(dplyr)
df <- df %>% 
         mutate(D = C[B == "Y"][cumsum(B == "Y")])
  

данные

 df <- structure(list(A = 1:10, B = c("Y", "", "", "", "", "Y", "", 
"", "Y", ""), C = c(10L, 11L, 2L, 5L, 8L, 2L, 3L, 45L, 1L, 0L
)), class = "data.frame", row.names = c(NA, -10L))
  

Ответ №3:

Я думаю, что ваша проблема может быть решена с помощью функций fill() from tidyr и dplyr :

 library(tidyverse)
#Data
df <- structure(list(A = 1:10, B = c("Y", "", "", "", "", "Y", "", 
"", "Y", ""), C = c(10L, 11L, 2L, 5L, 8L, 2L, 3L, 45L, 1L, 0L
)), class = "data.frame", row.names = c(NA, -10L))
  

Это выглядит как:

     A B  C
1   1 Y 10
2   2   11
3   3    2
4   4    5
5   5    8
6   6 Y  2
7   7    3
8   8   45
9   9 Y  1
10 10    0
  

Вы можете создать D с условием на основе B , а затем заполнить недостающие значения:

 #Code
df %>% mutate(D=ifelse(B=='Y',C,NA)) %>%
  fill(D)
  

Вывод:

     A B  C  D
1   1 Y 10 10
2   2   11 10
3   3    2 10
4   4    5 10
5   5    8 10
6   6 Y  2  2
7   7    3  2
8   8   45  2
9   9 Y  1  1
10 10    0  1