Сохранить вывод цикла for в R - PullRequest
1 голос
/ 09 июня 2019

Предположим, у меня есть биномиальное распределение, где n = 12, p = 0,2.Я делю этот образец на 4 блока (группы), каждый блок имеет размер группы 3. Затем я удаляю выход, сумма которого равна 0. Для остальных выходов я пытаюсь объединить все оставшиеся выходы в новыйвектор.Вот мой код

set.seed(123)
sample1=rbinom(12,1,0.2)
chuck2=function(x,n)split(x,cut(seq_along(x),n,labels=FALSE))
chunk=chuck2(sample1,4)
for (i in 1:4){
  aa=chunk[[i]]
  if (sum(aa)!=0){
    a.no0=aa
    print(a.no0)
  }
}

А вот и вывод:

[1] 1 1 0
[1] 0 1 0
[1] 0 1 0

Я хочу объединить эти три выхода в новый вектор, например:

[1] 1 1 0 0 1 0 0 1 0

, но яПонятия не имею, как это работает, какие-либо советы, пожалуйста?

Ответы [ 5 ]

2 голосов
/ 09 июня 2019
set.seed(123)
sample1=rbinom(12,1,0.2)
chuck2=function(x,n)split(x,cut(seq_along(x),n,labels=FALSE))
chunk=chuck2(sample1,4)  

int_vector <- c()

for (i in 1:4){
    aa=chunk[[i]]
    if (sum(aa)!=0){
        a.no0=aa
        int_vector <- c(int_vector, a.no0)
    }
}

int_vector
# [1] 1 1 0 0 1 0 0 1 0
0 голосов
/ 10 июня 2019

Похоже, ваша функция создает псевдоматрицу в виде списка. Вместо этого он непосредственно создает матрицу из sample1, а затем выводит вектор, где rowSums больше 0.

set.seed(123)
sample1 = rbinom(12, 1, 0.2)

chunk_mat = matrix(sample1, ncol = 3, byrow = T)

as.vector(t(chunk_mat[which(rowSums(chunk_mat) != 0), ]))

Вот эталонные тесты - у меня есть chuck2 в глобальной среде, но каждая функция все еще должна сгенерировать chunk фрейм данных / матрицу / список, чтобы они превратились из яблок в яблоки.

Unit: microseconds
            expr      min        lq       mean    median        uq       max neval
     cole_matrix   19.902   26.2515   38.60094   43.3505   47.4505    56.801   100
 heds_int_vector 4965.201 5101.9010 5616.53893 5251.8510 5490.9010 23417.401   100
 bwilliams_dplyr 5278.602 5506.4010 5847.55298 5665.7010 5821.5515  9413.801   100
      Simon_base  128.501  138.0010  196.46697  185.6005  203.1515  2481.101   100
  Simon_magrittr  366.601  392.5005  453.74806  455.1510  492.0010   739.501   100
0 голосов
/ 10 июня 2019

Две версии без цикла.

данные:

set.seed(123)
sample1 <- rbinom(12, 1, 0.2)

функциональная версия base-R:

split.sample1 <- split(sample1,cut(seq_along(sample1),4,labels=FALSE))
sumf <- function(x) if(sum(x) == 0) NULL else x
result <- unlist(lapply(split.sample1,sumf),use.names=F)

> result
[1] 1 1 0 0 1 0 0 1 0

современное использование трубы %>% версия оператора:

library(magrittr) # for %>% operator
grp.indx <- cut(seq_along(sample1),4,labels=FALSE)
split.sample1 <- sample1 %>% split(grp.indx)
result <- split.sample1 %>% lapply(sumf) %>% unlist(use.names=F)

> result
[1] 1 1 0 0 1 0 0 1 0
0 голосов
/ 09 июня 2019

Непосредственно не решает вашу проблему, но это может быть выполнено без цикла for:

library(dplyr)
set.seed(123)
sample1 <- rbinom(12, 1, 0.2)

as.data.frame(matrix(sample1, ncol = 3, byrow = TRUE)) %>% 
  mutate(test = rowSums(.), id = 1:n()) %>% 
  filter(test > 0) %>% 
  dplyr::select(-test) %>% 
  gather(key, value, -id) %>% 
  arrange(id, key) %>% 
  .$value
0 голосов
/ 09 июня 2019

Создайте list() и присвойте ему имя переменной. Затем вы добавляете эту переменную в цикл, затем append значения цикла в списке.

new_vector <- list()

for (i in 1:4){
  aa=chunk[[i]]
  if (sum(aa)!=0){
    a.no0=aa
    new_vector <- append(new_vector, a.no0)
  }
}
new_vector

Это вернет:

[[1]]
[1] 1

[[2]]
[1] 1

[[3]]
[1] 0

[[4]]
[1] 0

[[5]]
[1] 1

[[6]]
[1] 0

[[7]]
[1] 0

[[8]]
[1] 1

[[9]]
[1] 0

Но я думаю, вы хотите сглаженный вектор:

as.vector(unlist(new_vector))

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