R 使用“应用”从每行使用非空值创建一个新列
我有一个由3列组成的数据框,每列代表受访者所属的组。受访者属于其中一个群体,他们的任务是在他们所属的群体栏中提供他们的数字回答。因此,对于给定的行,另外两列将为空 我需要创建一个列来记录他们的分数,不管他们属于哪个组。关于Stackoverflow,有一个与我类似的问题,但它是针对Python的(请参阅) 以下是数据的外观以及我所做的工作:R 使用“应用”从每行使用非空值创建一个新列,r,dplyr,apply,R,Dplyr,Apply,我有一个由3列组成的数据框,每列代表受访者所属的组。受访者属于其中一个群体,他们的任务是在他们所属的群体栏中提供他们的数字回答。因此,对于给定的行,另外两列将为空 我需要创建一个列来记录他们的分数,不管他们属于哪个组。关于Stackoverflow,有一个与我类似的问题,但它是针对Python的(请参阅) 以下是数据的外观以及我所做的工作: library(dplyr) df <- data.frame(grp_A = c(13, NA, NA, NA, NA, 20, NA),
library(dplyr)
df <- data.frame(grp_A = c(13, NA, NA, NA, NA, 20, NA),
grp_B = c(NA, 59, 66, NA, NA, NA, NA),
grp_C = c(NA, NA, NA, 23, 42, NA, NA))
df$value <- apply(select(df, grp_A, grp_B, grp_C), 1,
function(x) x[!is.na(x)])
库(dplyr)
df无需使用apply
,因为对于每一行,您只有一个非NA值,我们可以使用max.col
获得该值,而无需担心关系
df$value <- df[cbind(1:nrow(df), max.col(!is.na(df)))]
df
# grp_A grp_B grp_C value
#1 13 NA NA 13
#2 NA 59 NA 59
#3 NA 66 NA 66
#4 NA NA 23 23
#5 NA NA 42 42
#6 20 NA NA 20
#7 NA NA NA NA
您的apply
不起作用的原因是您的最后一行有所有NA
s,并且x[!is.NA(x)]
失败。如果删除该行并运行函数,那么它将工作
apply(df[-7, ], 1,function(x) x[!is.na(x)])
# 1 2 3 4 5 6
#13 59 66 23 42 20
我们还可以通过删除NA
来找出每行的max
值,但对于所有NA
s的行,这将返回-Inf
apply(df, 1,max, na.rm = TRUE)
#[1] 13 59 66 23 42 20 -Inf
将Reduce
与dplyr::coalesce一起使用如何
library(dplyr)
df <- data.frame(grp_A = c(13, NA, NA, NA, NA, 20, NA),
grp_B = c(NA, 59, 66, NA, NA, NA, NA),
grp_C = c(NA, NA, NA, 23, 42, NA, NA))
mutate(df, value = Reduce(coalesce, df))
另一个选项是使用行和
:
df$value <- rowSums(df, na.rm = T)
df[df$value == 0, ] <- NA
基本RrowMeans
df$new=rowMeans(df,na.rm=T)
df
grp_A grp_B grp_C new
1 13 NA NA 13
2 NA 59 NA 59
3 NA 66 NA 66
4 NA NA 23 23
5 NA NA 42 42
6 20 NA NA 20
7 NA NA NA NaN
df$value <- rowSums(df, na.rm = T)
df[df$value == 0, ] <- NA
microbenchmark::microbenchmark(
Reduce = Reduce(coalesce, df),
purrr = purrr::reduce(df, coalesce),
rowMeans = rowMeans(df,na.rm=T),
rowSums = rowSums(df, na.rm = T),
cbind = df[cbind(1:nrow(df), max.col(!is.na(df)))],
times = 1000
)
Unit: microseconds
expr min lq mean median uq max neval cld
Reduce 83.507 107.2095 145.4134 121.4320 137.8410 12190.845 1000 a
purrr 205.667 269.1175 357.5908 304.8540 342.4135 24316.051 1000 b
rowMeans 129.089 159.3555 196.1438 174.4890 194.9095 5481.523 1000 a
rowSums 129.454 157.1680 197.2731 173.5775 196.0035 7685.874 1000 a
cbind 267.294 331.8385 408.3179 368.4860 410.2400 4533.050 1000 b
df$new=rowMeans(df,na.rm=T)
df
grp_A grp_B grp_C new
1 13 NA NA 13
2 NA 59 NA 59
3 NA 66 NA 66
4 NA NA 23 23
5 NA NA 42 42
6 20 NA NA 20
7 NA NA NA NaN