Объединение двух циклов в один с определенным условием в R

#r #loops #for-loop

#r #циклы #для цикла

Вопрос:

С помощью следующего x вектора я хотел бы создать вектор размера 6 (grt1) с двумя условиями. Для уникальных значений x , возьмите подраздел, как показано ниже. Для других grt1 подобных позиций 3,5, and 6 данные из std нормальные.

 h=c(1:6)
grt1=numeric(length(h)) #Null vector
x=c(1,2,2,4,4,4)
for (i in unique(x)){
  f=rep(x[x==i],3)
  grt1[i]=sum(f)
} ##Condition-1
 for( j in c(3,5,6))
 {
   grt1[j]=rnorm(1) 
 } ##Condition 2
 

Приведенный выше код работает. Но я хочу сделать их общим утверждением, не указав c(3,5,6) во втором условии.

Любая помощь приветствуется.

Ответ №1:

Вот вариант с split

 v1 <- sapply(split(x, x), function(x) sum(rep(x, 3)))
grt1[grt1 == 0] <- rnorm(sum(grt1 == 0))
grt1
#[1]  3.0000000 12.0000000  0.3993774 36.0000000 -0.8149975 -1.2508617
 

Если нам нужно использовать цикл OP, получите индекс элементов, которые равны 0 (поскольку ‘grt1’ инициализируется как numeric вектор из 0s) с which помощью, выполните цикл над ним и назначьте эти элементы с помощью rnorm

 for(j in which(grt1 == 0))  grt1[j] <- rnorm(1)
grt1
#[1]  3.000000 12.000000 -0.765245 36.000000 -1.350172 -1.081518
 

ПРИМЕЧАНИЕ: rnorm is Vectorized , поэтому for цикл здесь на самом деле не нужен


Или с tidyverse

 library(dplyr)
library(tidyr)
tibble(x) %>% 
   group_by(x) %>%
   summarise(Sum = sum(rep(x, 3)), .groups = 'drop') %>%
   complete(x = h) %>% 
   transmute(Sum = replace(Sum, is.na(Sum), rnorm(sum(is.na(Sum))))) %>%
   pull(Sum)
#[1]  3.0000000 12.0000000 -1.9279778 36.0000000  0.7900143 -0.2506099
 

Комментарии:

1. Есть ли какой-нибудь способ, которым я могу это сделать, используя любой цикл?

2. @Uddin Я предполагаю, что ваш вопрос заключался в том, чтобы изменить руководство 3, 5, 6, верно? Обновленный код делает это

Ответ №2:

which(duplicated(x)) дал бы тебе c(3, 5, 6) . Попробуйте :

 inds <- which(duplicated(x))

for (i in unique(x)) {
  f=rep(x[x==i],3)
  grt1[i]=sum(f)
} 
for( j in inds){
  grt1[j]=rnorm(1) 
}