Usando funções tidyverse, pretendo criar uma nova coluna de dados que some a soma cumulativa na primeira coluna, mas use incrementos não maiores que incr
.
Isso poderia começar com df
incr <- 1.5
df <- data.frame(a = c(6,0,0,2.5,0,0))
df
a
1 6.0
2 0.0
3 0.0
4 2.5
5 0.0
6 0.0
em seguida, crie uma nova coluna b
usando incr
:
a b
1 6.0 1.5
2 0.0 1.5
3 0.0 1.5
4 2.5 1.5
5 0.0 1.5
6 0.0 1.0
Encontrei tidyr::uncount()
e parecia uma função que poderia funcionar, mas preciso usar incrementos não inteiros. Geralmente tento transformar e usar funções vetorizadas e pensei um pouco para executá-las rowwise()
, mas a maioria das minhas ideias requer iteração.
Do comentário abaixo: Se as analogias forem úteis, pense nisso como downloads em fila. A coluna a
mostra que você pressiona para baixar 6 MB no tempo 1, 0 MB para os tempos 2 e 3, depois pressiona para baixar 2,5 MB no tempo 4. Sua conexão, no entanto, só pode baixar na velocidade de incr
. Então, se incr
for 1,5, a coluna b
mostra o que realmente foi baixado. Você usa totalmente essa velocidade de conexão a cada período até baixar o resíduo final ( 1.0
) no tempo 6.
Para destacar melhor a dimensionalidade, aqui está outro df:
incr <- 1.5
df <- data.frame(a = rep(0,100),b=rep(0,100))
df$a[c(30,33,38)] = c(6,2.5,1)
df[30:39,]
a b
30 6.0 0
31 0.0 0
32 0.0 0
33 2.5 0
34 0.0 0
35 0.0 0
36 0.0 0
37 0.0 0
38 1.0 0
39 0.0 0
com uma saída desejada
a b
30 6.0 1.5
31 0.0 1.5
32 0.0 1.5
33 2.5 1.5
34 0.0 1.5
35 0.0 1.0
36 0.0 0.0
37 0.0 0.0
38 1.0 1.0
39 0.0 0.0
porque não sei quando desistir, acho que a única solução é a iteração. Mas acho que você sempre pode fazer iterações em C++ para torná-lo tão rápido quanto uma função vetorizada:
Uma possibilidade é usar uma fábrica de funções. Isso permite salvar algumas informações de estado, neste caso um restante, o que é útil para o seu cálculo. A iteração vem de dentro
map_dbl
, mas esta não é uma resposta vetorizada:Farei isso com um
for
loop com váriasif
instruções:Configurar dataframe
For
loop eif
instruções:Saída
Em termos de implementação, usei a função Rcpp do @Andy Baxter e funcionou muito bem!
Para futuros usuários que desejam resolver isso apenas com o tidyverse e sem C++: Concordando com a conclusão de @Andy Baxter de que isso exigiria iteração, desenvolvi um método viável, embora desajeitado, começando
case_when()
com a linha 100df
acima: