Как запустить для l oop по всем столбцам фрейма данных и вернуть результат в виде отдельного фрейма данных или матрицы - PullRequest
1 голос
/ 20 июня 2020

Я пытаюсь получить количество наблюдений для каждой переменной в df. В df 275 случаев, но в большинстве столбцов отсутствуют некоторые данные. Я пытаюсь запустить для l oop, чтобы получить следующую информацию:

idef_id<-readxl::read_xlsx("IDEF.xlsx")

casenums <- for (i in names(idef_id)) {
  nas<- sum(is.na(i))
  275-nas
}

, однако результат для casenums равен

> summary(casenums)
Length  Class   Mode 
     0   NULL   NULL 

Любая помощь будет очень принята !

Ответы [ 2 ]

1 голос
/ 20 июня 2020

A for l oop не является функцией - он ничего не возвращает, поэтому x <- for(... не имеет смысла. Вы можете сделать это, например, sapply, как это

casenums <- sapply(idef_id, function(x) sum(!is.na(x)))

Или вы можете сделать это в for l oop, но вам нужно присвоить определенное значение внутри l oop:

casenums = rep(NA, ncol(idef_id))
names(casenums) = names(idef_id)
for(i in names(idef_id)) {
  casenums[i] = sum(!is.na(idef_id[[i]]))`
}

У вас также была проблема, что i принимает имена столбцов, поэтому sum(is.na(i)) спрашивает, отсутствует ли значение имени столбца. Вам нужно использовать idef_id[[i]] для доступа к фактическому столбцу, а не только к имени столбца, как я показал выше.

Кажется, вы хотите, чтобы ответом было количество значений, отличных от NA, поэтому я переключился на sum(!is.na(...)), чтобы подсчитать это напрямую, а не жестко кодировать количество строк кадра данных и выполнять вычитание.

0 голосов
/ 20 июня 2020

Немедленное исправление для вашего for l oop состоит в том, что ваш i является столбцом name , а не данными внутри. При первом проходе через for l oop ваш i - это класс character, всегда длина 1, поэтому sum(is.na(i)) будет 0. Из-за того, как структурированы кадры, вероятность очень мала. что name равно NA (хотя это возможно ... с ручной уловкой).

Я предлагаю буквальное исправление для вашего кода:

casenums <- for (i in names(idef_id)) {
  nas<- sum(is.na(idef_id[[i]]))
  275-nas
}

Но у этого есть дополнительная проблема, что for циклы ничего не возвращают (как также обсуждает ответ Грегора). Чтобы пройтись по вещам, я сохраню это (для первой пули), а затем исправлю (во второй):

Две вещи:

  • жесткое кодирование 275 (при условии, что количество строк в кадре) будет проблематично c, если / когда ваши данные когда-либо изменятся. Даже если вы "уверены", этого никогда не случится ... Я все же рекомендую не кодировать жестко. Если он основан на количестве строк, то, возможно,

    OUT_OF <- 275 # should this be nrow(idef_id)?
    casenums <- for (i in names(idef_id)) {
      nas<- sum(is.na(idef_id[[i]]))
      OUT_OF - nas
    }
    

    по крайней мере в декларативном смысле, где имя переменной (пожалуйста, выберите что-нибудь получше) ясно относительно того, как вы определили 275 и как (при необходимости) это должно быть исправлено в будущем.

    (Или лучше, используйте логи Грегора c из sum(!is.na(...)), если вам просто нужно считать не- NA.)

  • выполнение чего-либо для каждого столбца кадра легко выполняется с помощью sapply или lapply, возможно,

    OUT_OF <- 275 # should this be nrow(idef_id)?
    OUT_OF - sapply(idef_id, function(one_column) sum(is.na(one_column)))
    ## or
    sapply(idef_id, function(one_column) OUT_OF - sum(is.na(one_column)))
    
...