Странные "переменчивые" результаты в l oop в R - PullRequest
3 голосов
/ 18 апреля 2020

Обновление2

Второй set.seed(i) должен быть заменен на set.seed(i+1) или любой другой новый случайный ряд. Если нет, то s3 <- sum(data$gene == 0 & data$cancer == 1) всегда будет 0, так как число меньше 0.08 будет меньше 0.39.

Я не исправил свой исходный код вопроса, потому что этот вопрос не связан к основному вопросу этого поста.

Обновление

set.seed(i) добавляется дважды, поскольку существует два поколения случайных чисел, то есть random1 и random2. Тем не менее, результаты среди операций все еще изменчивы, что странно.

Справочная информация:

приведенные ниже коды примерно равны шансы крысы ios. Но точка фокусировки здесь не статистическая c. Вместо этого я обнаружил, что результаты изменились (!) Среди некоторых операций, которые на самом деле одинаковы (я полагаю, что на самом деле это не так, но я не могу это выяснить).

Код:

gene <- vector(length = 500, mode = "integer")
cancer <- vector(length = 500, mode = "integer")
data <- data.frame(gene, cancer)

odd_withMutate <- vector(length = 20, mode = "numeric")
odd_noMutate   <- vector(length = 20, mode = "numeric")
result <- data.frame(odd_withMutate, odd_noMutate)

for (i in 1:20) {
  # set.seed(12)   
  # set.seed(16)   
  set.seed(i)
  random1 <- runif(500, min = 0, max = 1)
  # set.seed(12)   
  # set.seed(16)
  set.seed(i)   # add this instruction
  random2 <- runif(500, min = 0, max = 1)
  for (j in 1:500) {
    if (random1[j] < 0.39){
      data[j,1] <- 1
    }
    if (random2[j] < 0.08){
      data[j,2] <- 1
    }
  }
  s1 <- sum(data$gene == 1 & data$cancer == 1)  # has the mutated gene & has cancer  
  s2 <- sum(data$gene == 1 & data$cancer == 0) 
  s3 <- sum(data$gene == 0 & data$cancer == 1)
  s4 <- sum(data$gene == 0 & data$cancer == 0)
  result[i,]$odd_withMutate <- s1/s2
  result[i,]$odd_noMutate   <- s3/s4    
}

Различные операции:

Операция № 1:

Если запустить код, указанный выше, 12-я строка odd_noMutate in result будет 0, 16-е будет NaN. Затем я попытался увидеть, что произошло, поэтому я использую set.seed(12) или set.seed(16) для проверки (Операции № 2 и № 3). Но 0 и NaN исчезли! Я имею в виду, что в операции № 2 0.1638418 0 не 1.5075377 0. В операции № 3 0.2830189 0 не является 2.4013605 NaN.

операцией № 2:

измененная часть кода:

  set.seed(12)   #odd_noMutate = 0
  # set.seed(16)   #odd_noMutate = NaN
  # set.seed(i)
  random1 <- runif(500, min = 0, max = 1)
  set.seed(12)
  # set.seed(16)
  # set.seed(i)   # add this instruction
  random2 <- runif(500, min = 0, max = 1)

операция № 3:

  # set.seed(12)   #odd_noMutate = 0
  set.seed(16)   #odd_noMutate = NaN
  # set.seed(i)
  random1 <- runif(500, min = 0, max = 1)
  # set.seed(12)
  set.seed(16)
  # set.seed(i)   # add this instruction

Операция № 4:

Я обнаружил, что даже изменение i в моем коде приведет к совершенно другим результатам (не должно ли это быть подмножество исходного результата?) , Это операция № 4. В частности, 0.3092105 0 не является 1.5075377 0; 0.7562724 0 не 2.4013605 NaN.

for (i in 10:20) {
  # set.seed(12)   #odd_noMutate = 0
  # set.seed(16)   #odd_noMutate = NaN
  set.seed(i)
  random1 <- runif(500, min = 0, max = 1)
  # set.seed(12)
  # set.seed(16)
  set.seed(i)   # add this instruction
  random2 <- runif(500, min = 0, max = 1)

Результаты этих операций показаны ниже: Result

1 Ответ

2 голосов
/ 20 апреля 2020

Проблема в том, что некоторые предыдущие значения в data остаются и используются повторно. Возможно, ваша проблема решена переделкой data каждый для l oop (i). (ввод data <- data.frame(gene, cancer) для l oop).

gene <- vector(length = 500, mode = "integer")
cancer <- vector(length = 500, mode = "integer")
# data <- data.frame(gene, cancer)

odd_withMutate <- vector(length = 20, mode = "numeric")
odd_noMutate   <- vector(length = 20, mode = "numeric")
result <- data.frame(odd_withMutate, odd_noMutate)

for (i in 1:20) {
  data <- data.frame(gene, cancer)  # remaking data every time
  # set.seed(12)   
  # set.seed(16)   
  set.seed(i)
  random1 <- runif(500, min = 0, max = 1)
  # set.seed(12)   
  # set.seed(16)
  set.seed(i)   # add this instruction
  random2 <- runif(500, min = 0, max = 1)
  for (j in 1:500) {
    if (random1[j] < 0.39){
      data[j,1] <- 1
    }
    if (random2[j] < 0.08){
      data[j,2] <- 1
    }
  }
  s1 <- sum(data$gene == 1 & data$cancer == 1)  # has the mutated gene & has cancer  
  s2 <- sum(data$gene == 1 & data$cancer == 0) 
  s3 <- sum(data$gene == 0 & data$cancer == 1)
  s4 <- sum(data$gene == 0 & data$cancer == 0)
  result[i,]$odd_withMutate <- s1/s2
  result[i,]$odd_noMutate   <- s3/s4    
}


[ДОПОЛНЕНИЕ]

for l oop не имеет собственную среду в отличие от функции.
Таким образом, обработка в for l oop напрямую влияет на объекты Global env, такие как data.
Вы частично переписали data Global env Если заявление и оно было указано в следующем l oop.

Вот мой простой пример;

data <- data.frame(gene = vector(length = 5, mode = "integer"))
keep_of_process <- list()

for(i in 1:2) {

  set.seed(i)
  random_val <- runif(5, 0, 1)

  for(j in 1:5) {
    if(random_val[j] < 0.39) {
      data[j, 1] <- 1
    }

    keep_of_process[[i]] <- data.frame(random = random_val,
                                       gene = data$gene)
  }
}


do.call("cbind", keep_of_process)  # just to merge process to show
 # left is i = 1 and right is i = 2

     random gene    random gene
1 0.2655087    1 0.1848823    1
2 0.3721239    1 0.7023740    1
3 0.5728534    0 0.5733263    0
4 0.9082078    0 0.1680519    1
5 0.2016819    1 0.9438393    1

Пожалуйста, см. строку 2. В i = 2, random равно 0,7023740, но ген равен 1 (предыдущий результат сохраняется).

Итак, чтобы сделать то, что вы хотите (из моего понимания), вам нужно переделать data (мой ответ) или полностью перезаписать data оператором if, например

if(random_val[j] < 0.39) {
      data[j, 1] <- 1
    } else {
      data[j, 1] <- 0
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...