Multiplicar ocorrências de uma lista baseada em outra

Olá, pessoal! Tudo bem?
Comecei a trabalhar com R recentemente e estou com uma dúvida que não estou conseguindo sanar. Poderiam me ajudar, por favor?
Tenho uma lista chamada “itens” que indica o nome dos produtos que foram comprados por um cliente em um mercado. Esta lista está dentro de outra denominada “compras”, que também indica o nome do estabelecimento e o nome da pessoa que realizou a compra.
Eu também tenho uma outra lista chamada “quantidades” que indica apenas a quantidade de unidades de cada item que foi adquirido pelo cliente.
Gostaria de modificar a lista “itens” alterando a quantidade de vezes que cada produto comprado aparece de acordo com o número correspondente indicado em “quantidades”. Obs.: As listas “itens” e “quantidades” têm o mesmo tamanho.

compras <- list("mercado" = "compre bem", "cliente" = "maria", 
                "itens" = list("ovo", "carne", "arroz", "banana"))
compras
#> $mercado
#> [1] "compre bem"
#> 
#> $cliente
#> [1] "maria"
#> 
#> $itens
#> $itens[[1]]
#> [1] "ovo"
#> 
#> $itens[[2]]
#> [1] "carne"
#> 
#> $itens[[3]]
#> [1] "arroz"
#> 
#> $itens[[4]]
#> [1] "banana"

quantidades <- list(2, 4, 1, 3)
quantidades 
#> [[1]]
#> [1] 2
#> 
#> [[2]]
#> [1] 4
#> 
#> [[3]]
#> [1] 1
#> 
#> [[4]]
#> [1] 3

#Resultado esperado
compras_new <- list("supermercado" = "compre bem", "cliente" = "maria", 
                    "itens" = list("ovo", "ovo", "carne", "carne", "carne", 
                                   "carne", "arroz", "banana", "banana", 
                                   "banana"))
compras_new
#> $supermercado
#> [1] "compre bem"
#> 
#> $cliente
#> [1] "maria"
#> 
#> $itens
#> $itens[[1]]
#> [1] "ovo"
#> 
#> $itens[[2]]
#> [1] "ovo"
#> 
#> $itens[[3]]
#> [1] "carne"
#> 
#> $itens[[4]]
#> [1] "carne"
#> 
#> $itens[[5]]
#> [1] "carne"
#> 
#> $itens[[6]]
#> [1] "carne"
#> 
#> $itens[[7]]
#> [1] "arroz"
#> 
#> $itens[[8]]
#> [1] "banana"
#> 
#> $itens[[9]]
#> [1] "banana"
#> 
#> $itens[[10]]
#> [1] "banana"

Created on 2022-06-30 by the reprex package (v2.0.1)

Nathan,

A primeira função necessária para essa tarefa é a rep(), que cria um vetor repetindo um elemento n vezes.

rep("ovo", 3)
#> [1] "ovo" "ovo" "ovo"

Created on 2022-06-30 by the reprex package (v2.0.1)

Usando essa função, podemos simplesmente fazer um loop nos itens da lista de compras, repetindo cada um de acordo com quantidades.

# Exemplo de compras
compras <- list(
  "mercado" = "compre bem",
  "cliente" = "maria", 
  "itens" = list("ovo", "carne", "arroz", "banana")
)

# Exemplo de quantidades
quantidades <- list(2, 4, 1, 3)

# Lista vazia
new_itens <- list()

# Com i de 1 a length(quantidades)...
for (i in seq_along(quantidades)) {

  # Repetir o item n vezes
  item_repetido <- rep(compras$itens[i], quantidades[i])

  # Juntar o item repetido no final da lista
  new_itens <- append(new_itens, item_repetido)
}

# Substituir os antigos itens pela nova lista
compras$itens <- new_itens

# Exibir de forma compacta
str(compras)
#> List of 3
#>  $ mercado: chr "compre bem"
#>  $ cliente: chr "maria"
#>  $ itens  :List of 10
#>   ..$ : chr "ovo"
#>   ..$ : chr "ovo"
#>   ..$ : chr "carne"
#>   ..$ : chr "carne"
#>   ..$ : chr "carne"
#>   ..$ : chr "carne"
#>   ..$ : chr "arroz"
#>   ..$ : chr "banana"
#>   ..$ : chr "banana"
#>   ..$ : chr "banana

Created on 2022-06-30 by the reprex package (v2.0.1)

Se você estiver interessado em uma maneira mais direta de resolver o problema, você pode usar o pacote purrr (para instalar, basta executar install.packages("purrr")). Não vou entrar em tantos detalhes sobre o código abaixo, mas o seu resultado é exatamente igual:

library(purrr)

# Exemplo de compras
compras <- list(
  "mercado" = "compre bem",
  "cliente" = "maria", 
  "itens" = list("ovo", "carne", "arroz", "banana")
)

# Exemplo de quantidades
quantidades <- list(2, 4, 1, 3)

# Mesmo efeito, mas em uma linha só
compras$itens <- flatten(map2(compras$itens, quantidades, rep))

Created on 2022-06-30 by the reprex package (v2.0.1)

1 curtida

Deu super certo, Caio! Muitíssimo obrigado!

1 curtida