Eu tenho um dataframe que desejo subconjunto selecionando apenas valores consecutivos de "1".
Especificamente, eu tenho um dataframe que se parece com isso:
library(tidyverse)
library(zoo)
df <- data.frame(matrix(ncol = 3, nrow = 17))
colnames(df) <- c("row_id","id", "k_yes")
df$row_id <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17)
df$id <- c("1_1","1_1","1_1","1_1","1_1","1_1","1_2","1_2","1_2","1_2","1_2","1_2","1_3","1_3","1_3","1_3","1_3")
df$k_yes <- c(1,1,1,0,1,1,0,0,0,1,1,0,1,0,1,0,1)
df
row_id id k_yes
1 1 1_1 1
2 2 1_1 1
3 3 1_1 1
4 4 1_1 0
5 5 1_1 1
6 6 1_1 1
7 7 1_2 0
8 8 1_2 0
9 9 1_2 0
10 10 1_2 1
11 11 1_2 1
12 12 1_2 0
13 13 1_3 1
14 14 1_3 0
15 15 1_3 1
16 16 1_3 0
17 17 1_3 1
E eu quero criar dois conjuntos de dados :
1) Aquele que, por grupo ( id
), tem apenas "1"'s, mas sempre dois ou mais consecutivos. Assim, se houver um "0" entre dois "1", pelo menos o último "1" deve ser descartado. Portanto, aceitaria sequências como, por exemplo 1-1
, 1-1-1
, e assim por diante, mas não 0-1-1
ou1-1-1-0
Então, também gostaria que fosse adicionada uma coluna para saber qual novo grupo/sequência foi formado, pois nem sempre será igual ao id (caso existam dois subgrupos/sequências dentro do id). Basicamente, esta coluna deve ter um código único por sequência para todo o dataframe (agora, acabei de vincular o id com uma letra, mas pode ser um número/letra consecutivo, por exemplo)
Este dataframe ficaria assim:
row_id id k_yes new_group
1 1 1_1 1 1_1_A
2 2 1_1 1 1_1_A
3 3 1_1 1 1_1_A
4 5 1_1 1 1_1_B
5 6 1_1 1 1_1_B
6 10 1_2 1 1_2_A
7 11 1_2 1 1_2_A
2) Outro que, por grupo ( id
), aceita um "0" entre os "1"s, mas não se não houver outros "1"s depois do "0". Então aceitaria sequências como por exemplo 1-0-1
, 1-1-0-1
, 1-1-0-1-1
, 1-1-0-1-0-1
, e assim por diante, mas não sequências como 0-1-1
ou 1-1-0
ou 1-1-0-0-1
(no último, manteria apenas os primeiros 1's). E o mesmo de antes para a coluna "new_group".
A saída desejada de df seria:
row_id id k_yes new_group
1 1 1_1 1 1_1_A
2 2 1_1 1 1_1_A
3 3 1_1 1 1_1_A
4 4 1_1 0 1_1_A
5 5 1_1 1 1_1_A
6 6 1_1 1 1_1_A
7 10 1_2 1 1_2_A
8 11 1_2 1 1_2_A
9 12 1_3 1 1_3_A
10 14 1_3 0 1_3_A
11 15 1_3 1 1_3_A
12 16 1_3 0 1_3_A
13 17 1_3 1 1_3_A
Nesse caso, id "1_1" obtém apenas um valor para "novo grupo" (1_1_A) porque é tudo a mesma sequência (com o 0 incluído)
Eu tentei seguir esta resposta , mas não funcionou, pois tentei:
> df |>
group_by(id) |>
mutate(b = c(first(k_yes) , zoo::rollsum(k_yes, 1))) |>
summarise(groups_to_keep = id[which(b >= 2)]) -> gk
Error in `mutate()`:
ℹ In argument: `b = c(first(k_yes), zoo::rollsum(k_yes, 1))`.
ℹ In group 1: `id = "1_1"`.
Caused by error:
! `b` must be size 5 or 1, not 6.
Acho que o problema é a rollsum()
função, mas depois de verificar a página de ajuda ainda não ficou claro para mim como essa função deve ser aplicada.
Qualquer ajuda é apreciada!
Atualizar:
Adicionei uma nova versão do conjunto de dados, que criaria dois valores para "novo grupo" no primeiro conjunto de dados (1).
Para o conjunto de dados nº 1:
Conjunto de dados 2: