对于每一行 return 非 NA 值的列索引和名称
For each row return the column index and name of non-NA value
我有一个数据框,其中每一行包含一个非 NA
值。
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
对于每一行,我想获取包含非 NA
值的列的索引和名称,即:
索引:c(1, 3, 2, 5)
,及其对应的列名:c("ED1" "ED3" "ED2" "ED5")
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
这里不需要使用apply()
循环。您可以将 max.col()
与对 is.na()
.
的否定调用结合使用
max.col(!is.na(df))
# [1] 1 3 2 5
这给了我们 1 所在的列号。要获取列名,我们可以在数据框 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")
另一种选择是
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"
我有一个数据框,其中每一行包含一个非 NA
值。
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
对于每一行,我想获取包含非 NA
值的列的索引和名称,即:
索引:c(1, 3, 2, 5)
,及其对应的列名:c("ED1" "ED3" "ED2" "ED5")
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
这里不需要使用apply()
循环。您可以将 max.col()
与对 is.na()
.
max.col(!is.na(df))
# [1] 1 3 2 5
这给了我们 1 所在的列号。要获取列名,我们可以在数据框 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")
另一种选择是
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"