Как сохранить результаты для-l oop в R, когда результат является вектором - PullRequest
1 голос
/ 11 апреля 2020

При зацикливании функции, которая создает вектор, я просто хочу сохранить результирующие векторы как один длинный вектор.

Это не работает:

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)
}

Таким образом, результат, сохраненный в cols, должен быть:

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

т.е. вектор 1x10 струн.

Ответы [ 3 ]

1 голос
/ 11 апреля 2020

Мы можем использовать mapply здесь:

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"
1 голос
/ 11 апреля 2020

Возможно, это не то, что вы ожидали (поместив тег for-l oop), но вам следует воздерживаться от использования R для циклов, когда это возможно. Вместо этого привыкните к использованию векторизованных операций для итераций. Они намного эффективнее и создают более читаемый код. Один из вариантов - использование mapply, другой - использование map (пакет purrr).

Функция tibble создает основы для итерации (если хотите, итератор).

Комбинация mutate и map - это то, что фактически выполняет функцию rainbow и сохраняет свои результаты в tibble.

Результаты представлены в виде списка в списке (символьный векторный столбец внутри таблицы), поэтому unnest используется для извлечения их обратно в обычный вектор.

В конце концов, чтобы получить его как простой вектор, вы можете использовать answer_tib$rainbow_val.

Обратите внимание, что вывод, который вы указали в вопросе, не соответствует выводу, который вы должны получить. Непонятно, почему, может быть, вы хотели использовать разные значения для start_s и 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"
1 голос
/ 11 апреля 2020

В ОП, post, столбцы 'cols' инициализируются значением length 0. Здесь можно добавить вектор при назначении ему в каждой итерации

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


cols
#[1] "#CC3D3DE6" "#AFCC3DE6" "#3DCC76E6" "#3D76CCE6" "#AF3DCCE6" "#B34747E6" "#9DB347E6" "#47B372E6"
#[9] "#4772B3E6" "#9D47B3E6"

Если бы ОП хотел работать не с фиксированным 0,1, чтобы вычесть

cols <- vector()
i1 <- seq(0, by = 0.1, length.out = grps)
for(i in seq_len(grps)) {
   if(i > 1){
    start_s <- start_s-i1[i]
     start_v <- start_v-i1[i]
     }  
     cols<- c(cols, rainbow(n_total, start_s, start_v, alpha = Alpha))
  }



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

Вместо этого было бы более эффективно инициализировать с заранее определенной длиной, а затем выполнить присвоение индекса. Но здесь есть некоторые вещи неопределенные, т. Е. Он выполняет проверку if и только если это ИСТИНА, тогда он выполняет присваивание

cols <- character(10)

ПРИМЕЧАНИЕ: OP запросил for l oop здесь. В R есть лучшие способы справиться с этим вместо for l oop

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...