невозможно выполнить итерацию с R - PullRequest
0 голосов
/ 29 мая 2020

Я практиковался с набором данных Titani c и добился устойчивого прогресса. Однако я застрял, когда пытаюсь заменить отсутствующие переменные «Возраст» на средний возраст в зависимости от определенных условий. Вот набор данных:

| Pclass | Name      |   Sex  | Age |
|:------:|:---------:|:------:|:---:|
|    2   |  officer  |  male  |  NA |
|    3   |  mr       |  male  |  27 |
|    3   |  miss     | female |  NA |

Теперь я хочу заменить NA на средний возраст, который я рассчитал, и оставить возраст как есть. Для этого я использовал следующий код для итерации:

age_fill <- function(x){ 

    for (i in length(x$Age)) {

      if (!is.na(x$Age[i])) {
          return(x$Age[i])

      }

      else if(is.na(x$Age[i])){


        if (x$Sex[i] == "female" && x$Pclass[i] == "3" && x$Name[i] == "miss"){
          x$Age[i] = 18
        }

        if (x$Sex[i] == "male" && x$Pclass[i] == "2" && x$Name[i] == "mr"){
          x$Age[i] = 29
        }

        if (x$Sex[i] == "male" && x$Pclass[i] == "3" && x$Name[i] == "officer"){
          x$Age[i] = 25
        }

     }

  }
  return(x)
}

Проблема здесь в том, что ничего не меняется, когда я запускаю код как функцию или l oop. Однако, если я запустил его отдельно, введя цифры в строке, он вернет результаты очень хорошо.

Может кто-нибудь, пожалуйста, скажет мне, что я делаю не так?

Ответы [ 2 ]

3 голосов
/ 29 мая 2020

Ваш вопрос

Относительно вашей функции есть несколько проблем:


age_fill <- function(x){ 

    for (i in length(x$Age)) {

      if (!is.na(x$Age[i])) {
          return(x$Age[i])

      }
# some more code
}
  1. Ваш for -l oop просто перебирает один элемент: length(x$Age) возвращает одно значение. Думаю, вы приняли его за 1:length(x$Age).

  2. Если ваша функция встречает значение, отличное от NA, return(x$Age[i]) прерывает / останавливает вашу функцию и возвращает одно значение. Не думаю, что ты этого хочешь. В случае значения, отличного от NA, вы хотите, чтобы ваша функция ничего не меняла. Поэтому вам следует удалить всю эту часть:

      if (!is.na(x$Age[i])) {
          return(x$Age[i])

      }

      else 

Ваше состояние

if(is.na(x$Age[i])){
# enter code here
}

достаточно.

Альтернативный подход

Вот решение, использующее dplyr. Это не прямой ответ на ваш вопрос, но я хочу показать вам другой подход к вашей проблеме. Учитывая набор данных

> df
# A tibble: 6 x 4
  Pclass Name    Sex      Age
   <dbl> <chr>   <chr>  <dbl>
1      2 officer male      NA
2      3 mr      male      27
3      3 miss    female    NA
4      3 mr      male      NA
5      2 mr      male      NA
6      3 officer male      NA

, который я создал с помощью пакета readr

df <- read_table2("Pclass  Name        Sex   Age
    2     officer    male    NA 
    3     mr         male    27 
    3     miss       female   NA 
    3     mr         male     NA
    2     mr         male     NA
    3     officer    male     NA")

Теперь мы используем mutate в сочетании с case_when

df %>%
  mutate(Age = case_when(!is.na(Age) ~ Age,
                         Sex == "male"   & Pclass == "3" & Name == "officer" ~ 25,
                         Sex == "male"   & Pclass == "2" & Name == "mr"      ~ 29,
                         Sex == "female" & Pclass == "3" & Name == "miss"    ~ 18
                        ))

, который дает

# A tibble: 6 x 4
  Pclass Name    Sex      Age
   <dbl> <chr>   <chr>  <dbl>
1      2 officer male      NA
2      3 mr      male      27
3      3 miss    female    18
4      3 mr      male      NA
5      2 mr      male      29
6      3 officer male      25

Используя этот подход, вам не нужна функция или какой-либо l oop, и ваши условия четко упорядочены. Практическое правило: старайтесь избегать петель. Обычно существуют более изощренные способы выполнения задачи без циклов. R использует «скрытые циклы» внутри функций, оптимизированных для производительности. Однако есть задачи, хорошо подходящие для циклов. Так что решение зависит от реальной задачи.

1 голос
/ 29 мая 2020

Я думаю, что функция имеет параметр x и возвращает x, но цикл for применяется к (как я полагаю) "гребенке" data.frame. Чтобы выполнить вызов функции output <- age_fill(comb), вы должны заменить comb$myVariable на x$myVariable, чтобы можно было применить все операции внутри цикла for.

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