Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
839 views
in Technique[技术] by (71.8m points)

r - For each row return the column index and name of non-NA value

I have data frame where each row contain one non-NA value.

ED1 ED2 ED3 ED4 ED5 
1   NA  NA  NA  NA 
NA  NA  1   NA  NA 
NA  1   NA  NA  NA 
NA  NA  NA  NA  1 

For each row, I want to get the index and name of the column containing the non-NA value, i.e.:

Indices: c(1, 3, 2, 5), and their corresponding column names: c("ED1" "ED3" "ED2" "ED5")

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There is no need to use an apply() loop here. You could use max.col() in combination with a negated call to is.na().

max.col(!is.na(df))
# [1] 1 3 2 5

That gives us the column numbers where the 1s are. To get the column names, we can use that in a vector subset of the names() of the data frame.

names(df)[max.col(!is.na(df))]
# [1] "ED1" "ED3" "ED2" "ED5"

So we can get the desired data frame, with factor column, by doing

data.frame(EDU = names(df)[max.col(!is.na(df))])
#   EDU
# 1 ED1
# 2 ED3
# 3 ED2
# 4 ED5

Data:

df <- structure(list(ED1 = c(1, NA, NA, NA), ED2 = c(NA, NA, 1, NA), 
    ED3 = c(NA, 1, NA, NA), ED4 = c(NA, NA, NA, NA), ED5 = c(NA, 
    NA, NA, 1)), .Names = c("ED1", "ED2", "ED3", "ED4", "ED5"
), row.names = c(NA, -4L), class = "data.frame")

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...