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:
ie un vecteur 1x10 de chaînes. [ 1] "# B34747E6" "# 9DB347E6" "# 47B372E6" "# 4772B3E6" "# 9D47B3E6" "# 994D4DE6" "# 8A994DE6" "# 4D996BE6" "# 4D6B99E6" "" # 8A4D99E6 "
3 Réponses :
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)
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.
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"
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"