Eu tenho um dataframe que se parece com:
df <-
data.frame(col1 = c(1,2,2,1,2,3,4,3,1,2),
col2 = c(11,6,5,7,11,7,7,4,5,5))
col1 col2
1 1 11
2 2 6
3 2 5
4 1 7
5 2 11
6 3 7
7 4 7
8 3 4
9 1 5
10 2 5
Os dados são organizados em subtotais aninhados; o nível do subtotal é especificado em col1
e o valor especificado em col2
.
Esses subtotais funcionam da seguinte maneira:
col1 = 1
é a soma de todos os valorescol1 = 2
nas linhas seguintes, até o ponto em que um novocol1 = 1
é alcançado.Da mesma forma,
col1 = 2
é a soma dos valores decol1 = 3
nas linhas seguintes (onde eles existem), até que um novocol1 = 2
ou acol1 = 1
seja alcançado.Da mesma forma,
col1 = 3
é a soma dos valores decol1 = 4
nas linhas seguintes (onde eles existem), até que um novocol1 = 3
ou umcol1 = 2
/col1 = 1
seja alcançado.E assim por diante para valores mais altos de
col1
(os dados reais têm um intervalo de 1:7).
Estou tentando escrever um pedaço de código para verificar as linhas de subtotal e sinalizar aquelas que estão incorretas.
col1 col2 col3
1 1 11 TRUE
2 2 6 NA
3 2 5 NA
4 1 7 FALSE
5 2 11 TRUE
6 3 7 TRUE
7 4 7 NA
8 3 4 NA
9 1 5 TRUE
10 2 5 NA
Neste exemplo, a linha 4 seria sinalizada como incorreta, pois a linha relevante col1 = 2
a seguir ( linha 5 ) soma 11.
Até agora, tenho uma função que me fornece a soma de todos os valores das camadas superiores seguintes, em vez daqueles anteriores a uma nova camada ser alcançada.
df |>
mutate(
col3 = sapply(row_number(), \(x) {
target <- if_else(col1 %in% c(1, 2), col1 + 1, NA)[x]
sum(col2[x:n()][col1[x:n()] == target])
})
)
e tenho uma função que me dá a distância até o novo grupo de camadas relevante:
df |>
mutate(
col3 = sapply(seq_len(n()), \(x) {
matches <- which(col1[-(1:x)] <= col1[x])
if (length(matches)) matches[1] else n() - x + 1
})
)
Estou tentando integrá-los fazendo com que a primeira função verifique apenas o que for relevante para aquela camada, ou seja, algo como:
df |>
mutate(
col3 = sapply(row_number(), \(x) {
target <- if_else(col1 %in% c(1, 2), col1 + 1, NA)[x]
matches <- which(col1[-(1:x)] <= col1[x])
if (length(matches)) matches[1] else n() - x + 1
sum(col2[x:matches][col1[x:matches] == target])
})
)