1
votes

Comment stocker les résultats d'une boucle for dans R lorsque le résultat est un vecteur

Lors d'une boucle sur une fonction qui produit un vecteur, je veux simplement pouvoir stocker les vecteurs résultants comme un vecteur long.

Cela ne fonctionne pas:

n_total <- 5
grps <- 2
start_s <- 0.7
start_v <- 0.8
Alpha <- 0.9

cols <- vector()
for(i in seq(grps)){
  if(i > 1){
    start_s <- start_s-0.1
    start_v <- start_v-0.1
  }
  cols[i] <- rainbow(n_total, start_s, start_v, alpha = Alpha)
}

Le résultat stocké dans cols devrait donc être:

[ 1] "# B34747E6" "# 9DB347E6" "# 47B372E6" "# 4772B3E6" "# 9D47B3E6" "# 994D4DE6" "# 8A994DE6" "# 4D996BE6" "# 4D6B99E6" "" # 8A4D99E6 "

ie un vecteur 1x10 de chaînes.


0 commentaires

3 Réponses :


1
votes

Dans les OP, post, le 'cols' est initialisé avec une longueur 0. Une option ici serait d'ajouter le vecteur en lui assignant à chaque itération

cols <- character(10)


1 commentaires

Je suis d'accord avec "REMARQUE: les OP ont demandé une boucle for ici", cependant, je pense qu'il est erroné d'un point de vue pédagogique de fournir exactement ce que l'OP a demandé, sans au moins mentionner que ce n'est pas la meilleure pratique de l'accomplir avec une boucle for . Vous devriez peut-être le mentionner dans la solution (ou même fournir l'alternative à côté) afin de la rendre plus complète.



1
votes

Nous pouvons utiliser mapply ici:

n_total <- 5
grps <- 2
start_s <- 0.7
start_v <- 0.8
Alpha <- 0.9


inds <- seq(0, by = 0.1, length.out = grps)
c(mapply(function(x, y) rainbow(n_total, x, y, alpha = Alpha), 
         start_s - inds, start_v - inds))

#[1] "#B34747E6" "#9DB347E6" "#47B372E6" "#4772B3E6" "#9D47B3E6" 
#    "#994D4DE6" "#8A994DE6" "#4D996BE6" "#4D6B99E6" "#8A4D99E6"


0 commentaires

1
votes

Ce n'est peut-être pas ce à quoi vous vous attendiez (après avoir placé la balise for-loop), mais vous devriez vous abstenir d'utiliser R pour les boucles lorsque vous le pouvez. Habituez-vous plutôt à utiliser des opérations vectorisées pour les itérations. Ils sont beaucoup plus efficaces et produisent un code plus lisible. Une option consiste à utiliser mapply , voici une autre approche utilisant map (le package purrr ).

Le tibble crée les bases de l'itération (l'itérateur si vous voulez).

La combinaison de mutate et map est ce qui exécute réellement la fonction rainbow et préserve ses résultats dans le tibble .

Les résultats sont fournis sous forme de liste dans une liste (une colonne de vecteur de caractères à l'intérieur du tibble), donc unnest est utilisé pour les extraire en un vecteur normal.

Finalement, pour l'obtenir sous forme de vecteur simple, vous pouvez utiliser answer_tib$rainbow_val.

Veuillez noter que la sortie que vous avez fournie dans la question n'est pas cohérente avec la sortie que vous devriez obtenir. On ne sait pas pourquoi vous vouliez peut-être utiliser des valeurs différentes pour start_s et start_v?

library(tidyverse)

n_total <- 5
set_alpha <- 0.9
start_s <- 0.7
start_v <- 0.8

answer_tib <- tibble(run_index = seq(0, 0.1, by = 0.1)) %>% 
  mutate(rainbow_val = map(run_index, ~{
    rainbow(n = n_total, start_s - .x, start_v - .x, alpha = set_alpha)
  })) %>% 
  unnest(rainbow_val)

answer_tib$rainbow_val
#>  [1] "#CC3D3DE6" "#AFCC3DE6" "#3DCC76E6" "#3D76CCE6" "#AF3DCCE6" "#B34747E6"
#>  [7] "#9DB347E6" "#47B372E6" "#4772B3E6" "#9D47B3E6"


0 commentaires