Использование if / else, вложенного в цикл for, для перебора и переназначения значений в столбце в R?

#r

#r

Вопрос:

Я знаю, что это не самый эффективный способ достижения моей цели; однако я использую это как обучающий момент (т. Е. Чтобы Показать, что вы можете использовать оператор if / else, вложенный в цикл for). В частности, у меня есть номинальная переменная, которая использует целые числа на данный момент. Я хочу использовать if / else в сочетании с циклом for, чтобы переназначить эти числа в их соответствующую категорию (символ класса). Я пытался сделать это несколькими способами, мой текущий код выглядит следующим образом:

 # Take the original data and separate out the variable of interest
oasis_CDR <- oasis_final %>% select('CDR')

# transpose this data 
oasis_CDR <- t(oasis_CDR)

# create the for loop
for(i in seq_along(oasis_CDR)){
  if(i == 0.0){
    oasis_CDR[1, i] <- "Normal"
  } else if(i == 0.5) {
    oasis_CDR[1 ,i] <- "Very Mild Dementia"
  } else if(i == 1.0){
    oasis_CDR[1 ,i] <- "Mild Dementia"
  } else if(i == 2.0){
    oasis_CDR[1 ,i] <- "Moderate Dementia"
  } else if(i == 3.0){
    oasis_CDR[1 ,i] <- "Severe Dementia"
  } else{
    oasis_CDR[1 ,i] <- "NA"
  }
}
  

Когда я смотрю на oasis_CDR, он возвращает ‘NA’ для всех наблюдений.

Если я заменяю ‘i’ на ‘CDR’ в каждом операторе ‘for’, он возвращает только ‘Normal’.

Есть ли какой-либо способ, которым это можно сделать, чтобы переназначения соответствовали данным?

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

1. Набор данных, который я использую, предоставляется в свободном доступе Исследовательским центром болезни Альцгеймера Вашингтонского университета, доктором Рэнди Бакнером из Медицинского института Говарда Хьюза (HHMI) (в Гарвардском университете, Исследовательской группой по нейроинформатике (NRG) в Медицинской школе Вашингтонского университета и Исследовательской сетью биомедицинской информатики (BIRN). Его можно найти по адресу ( kaggle.com/jboysen/mri-and-alzheimers ). Я только удалил строки с помощью NAs до приведенного выше кода (таким образом, создав ‘oasis_final’)

2. Как сказано ниже, seq_along возвращает целые 1:length(oasis_CDR) числа . Таким образом, вы никогда не получите i = 0.5 .

3. Во-вторых, вы делаете oasis_CDR <- t(oasis_CDR) то, что превращает данные в вектор. Поэтому ссылка на oasis_CDR[1,1] бессмысленна. Это не фрейм данных или матрица.

Ответ №1:

Если у вас есть другое значение для присвоения каждому номеру, вы можете использовать dplyr::recode

 library(dplyr)

oasis_CDR <- oasis_CDR %>%
                 mutate(new_col = recode(CDR, `0` = 'Normal', 
                                              `0.5` = 'Very Mild Dementia', 
                                               `1` = 'Mild Dementia', 
                                               `1.5` = 'Moderate Dementia', 
                                               `3` = 'Severe Dementia', 
                                               .default = NA_character_))
  

Ответ №2:

Запустите проверку вашего seq_along(oasis_CDR) выражения! Это будут ваши i значения. Я предполагаю, что вы действительно не хотите сравнивать 0.0, 0.5, 1 и 2 с 1 до> 220, не так ли? И если вы действительно хотите проработать это с помощью for цикла, а не с индексацией вектора, то не более ли вероятно, что вы хотите достичь чего-то подобного:

 oasis_CDR$result <- NA_character_
j <- 1
for (i in oasis_CDR) { 
 if (i == ...) oasis_CDR$result[j] <- 'Normal'
... 
j <- j   1 
}
  

Но имхо, это может выполнить работу, но не является (очень) приятным кодом R (или любого другого подобного языка).