Сохранить первое не пропущенное значение в новом столбце - PullRequest
0 голосов
/ 13 сентября 2018

Чао, у меня есть несколько столбцов, которые представляют баллы.Для каждого СТУДЕНТА я хочу взять первый не-NA балл и сохранить его в новом столбце с именем TEST.

Вот мой реплицирующий пример.Это данные, которые у меня сейчас есть:

df <- data.frame(STUDENT=c(1,2,3,4,5), 
                 CLASS=c(90,91,92,93,95),
                 SCORE1=c(10,NA,NA,NA,NA), 
                 SCORE2=c(2,NA,8,NA,NA), 
                 SCORE3=c(9,6,6,NA,NA),
                 SCORE4=c(NA,7,5,1,9),
                 ROOM=c(01,02, 03, 04, 05))

Это столбец, который я собираюсь добавить:

df$FIRST <- c(10,6,8,1,9)

Это моя попытка:

df$FIRSTGUESS <- max.col(!is.na(df[3:6]), "first")

Ответы [ 4 ]

0 голосов
/ 13 сентября 2018

Это именно то, что делает coalesce из пакета dplyr.Как описано в документации:

Учитывая набор векторов, coalesce () находит первое не пропущенное значение в каждой позиции.

Следовательно, вы можете упростить:

library(dplyr)
df$FIRST <- do.call(coalesce, df[grepl('SCORE', names(df))])

Это результат:

> df
  STUDENT CLASS SCORE1 SCORE2 SCORE3 SCORE4 ROOM FIRST
1       1    90     10      2      9     NA    1    10
2       2    91     NA     NA      6      7    2     6
3       3    92     NA      8      6      5    3     8
4       4    93     NA     NA     NA      1    4     1
5       5    95     NA     NA     NA      9    5     9
0 голосов
/ 13 сентября 2018

К сожалению, max.col дает индексы максимальных значений, а не сами значения. Однако мы можем установить значения из исходного кадра данных с помощью вызова mapply.

#Select only columns which has "SCORE" in it
sub_df <- df[grepl("SCORE", names(df))]

#Get the first non-NA value by row 
inds <- max.col(!is.na(sub_df), ties.method = "first")

#Get the inds value by row
df$FIRSTGUESS <- mapply(function(x, y) sub_df[x,y], 1:nrow(sub_df), inds)

df

#  STUDENT CLASS SCORE1 SCORE2 SCORE3 SCORE4 ROOM FIRST FIRSTGUESS
#1       1    90     10      2      9     NA    1    10         10
#2       2    91     NA     NA      6      7    2     6          6
#3       3    92     NA      8      6      5    3     8          8
#4       4    93     NA     NA     NA      1    4     1          1
#5       5    95     NA     NA     NA      9    5     9          9
0 голосов
/ 13 сентября 2018

Использование zoo, na.locf, заимствование настройки sub_df из Ronak

 df['New']=zoo::na.locf(t(sub_df),fromLast=T)[1,]
 df
  STUDENT CLASS SCORE1 SCORE2 SCORE3 SCORE4 ROOM New
1       1    90     10      2      9     NA    1  10
2       2    91     NA     NA      6      7    2   6
3       3    92     NA      8      6      5    3   8
4       4    93     NA     NA     NA      1    4   1
5       5    95     NA     NA     NA      9    5   9
0 голосов
/ 13 сентября 2018

Вы можете сделать это с apply и which.min(is.na(...))

df$FIRSTGUESS <- apply(df[, grep("^SCORE", names(df))], 1, function(x) 
    x[which.min(is.na(x))])
df
#  STUDENT CLASS SCORE1 SCORE2 SCORE3 SCORE4 ROOM FIRSTGUESS
#1       1    90     10      2      9     NA    1         10
#2       2    91     NA     NA      6      7    2          6
#3       3    92     NA      8      6      5    3          8
#4       4    93     NA     NA     NA      1    4          1
#5       5    95     NA     NA     NA      9    5          9

Обратите внимание, что нам нужно is.na вместо !is.na, поскольку FALSE соответствует 0, и мы хотим вернуть первое (which.min) FALSE значение.

...