将多个具有大量NA的列组合到R中的一个因子列中

时间:2015-12-24 21:28:08

标签: r csv

我有一个带有观察结果的.csv导入表。

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 

< -----等------>

因此每行只包含一个值“1”,一行中的其他列包含NA。我需要将这五列合并为一个因子列。

像:

EDU

2

3

3

1

2

1

或者这可能是因子列“ED1”,“ED2”,“ED3”等因素(作为源列的名称)。

3 个答案:

答案 0 :(得分:6)

此处无需使用apply()循环。您可以将max.col()与对is.na()的否定调用结合使用。

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

这给了我们1s的列号。要获取列名称,我们可以在数据框的names()的向量子集中使用它。

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

所以我们可以通过

获得所需的数据框,包括因子列
data.frame(EDU = names(df)[max.col(!is.na(df))])
#   EDU
# 1 ED1
# 2 ED3
# 3 ED2
# 4 ED5

数据:

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")

答案 1 :(得分:1)

df <- data.frame( 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)  )

df_new <- data.frame( EDU = as.factor(apply(df,1,which.min)) )
levels(df_new$EDU) <- paste0("ED",levels(df_new$EDU))

> df
  ED1 ED2 ED3 ED4 ED5
1   1  NA  NA  NA  NA
2  NA  NA   1  NA  NA
3  NA   1  NA  NA  NA
4  NA  NA  NA  NA   1
> df_new
  EDU
1 ED1
2 ED3
3 ED2
4 ED5

答案 2 :(得分:1)

另一种选择是

 v1 <- names(df)[+(!is.na(df)) %*% seq_along(df)]
 v1
 #[1] "ED1" "ED3" "ED2" "ED5"

 data.frame(EDU=v1)

或使用pmax

names(df)[do.call(pmax, c(df *col(df), list(na.rm=TRUE)))]
#[1] "ED1" "ED3" "ED2" "ED5"