Ciao,我有几列代表分数。对于每个学生,我要获取第一个非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")
答案 0 :(得分:2)
您可以使用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
){{1} }值。
答案 1 :(得分:2)
这正是软件包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
答案 2 :(得分:1)
不幸的是,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
答案 3 :(得分:0)
使用zoo
,na.locf
,从Ronak借用sub_df
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