Как удалить переменные в панельных данных, если все наблюдения за данный год являются NAs?

#r #dataframe #data-manipulation #panel-data

#r #dataframe #манипулирование данными #панель-данные

Вопрос:

У меня есть такой фрейм данных,

 scores <-structure(list(student = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 
3L, 3L, 3L), .Label = c("adam", "mike", "rose"), class = "factor"), 
    year = c(2001L, 2002L, 2003L, 2001L, 2002L, 2003L, 2001L, 
    2002L, 2003L), math = c(5L, 3L, 5L, 3L, 2L, 4L, 4L, 2L, NA
    ), english = c(2L, NA, 5L, 4L, NA, 3L, 4L, NA, 4L), history = c(NA, 
    4L, 5L, NA, 3L, 4L, NA, 5L, 3L), geography = c(4L, 5L, 5L, 
    5L, 4L, 4L, 3L, 5L, 3L)), class = "data.frame", row.names = c(NA, 
-9L))
  

Я хочу удалить переменную, для которой ни один студент не набрал баллов за данный год. Например, ни у одного ученика не было баллов по английскому языку в 2002 году, поэтому я хочу удалить переменную «английский», если мой соответствующий год 2002. Аналогично, ни один студент не получил оценку по истории в 2001 году. Итак, если мой соответствующий год 2001, переменная «история» должна быть удалена. Если моим соответствующим годом является 2003 год, ни одна переменная не удаляется, потому что по крайней мере один ученик (точнее, Майк и Адам) имеет оценку в переменной «математика».

Для этого я создал следующую функцию, которая выполняет эту работу

 byearNA<-function(x,z = 3, ano = 2001) {
    matri <- data.frame(matrix(, nrow=nrow(x), ncol=(z-1)))
    matri <- x[c(1:(z-1))]
    for (i in z:ncol(x)){
        if (all(is.na(x[x[2] == ano,i]))==FALSE) {
            matri <- cbind(matri,x[i])
        }
    }
    return(matri)
}
  

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

Как я могу выполнить эту задачу с помощью встроенных функций в R?

Заранее большое спасибо

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

1. Я думаю, вам может быть лучше сохранить эти данные в длинном формате, например: scolong <- reshape(scores, idvar=c("student","year"), varying=list(-(1:2)), times=names(scores)[-(1:2)], direction="long") Тогда легко просто отбросить целые измерения, используя указанные ниже na.omit , не затрагивая другие действительные измерения — na.omit(scolong[scolong$year == 2002,])

Ответ №1:

Я не уверен на 100%, что вы ищете, но вы пробовали это?

 scores2 <- na.omit(scores)
  

Это вернет 2 строки, в которых есть полные наблюдения (без значений NA)

добавление нескольких строк после комментариев к электронной почте … сохранение в длинном формате — хорошая идея. вам нужно будет работать с длинным фреймом данных, если вы не хотите видеть значения NA в своей таблице. вот метод dplyr

 scores_gathered <- gather(scores, "class", "count", 3:6) 

scores_gathered <-scores_gathered %>%
  group_by(year, class) %>%
  summarize(sum = sum(count))

complete_list <- scores_gathered %>%
  drop_na(sum) %>%
  select(year, class) %>%
  mutate(has_students = "yes")
  

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

1. Дорогой Джозеф, большое спасибо за ваш быстрый ответ. Однако я не ищу полные случаи. В панельных данных у нас есть наблюдения для отдельных лиц, для которых есть данные за несколько лет. Итак, как и в моем примере, у каждого человека (Адама, Майка и Роуз) могут быть данные за несколько лет (2001, 2002 и 2003). Затем я хочу удалить все переменные, для которых ни у кого нет данных за данный год. Например, предположим, что интересующий меня год — 2002. если переменный вес не был измерен в 2002 году ни для одного человека (ни одно тело не было взвешено в этом году), я хочу удалить переменный вес.