我有一个由3列组成的数据框,每一列代表受访者所属的组。受访者属于这些组之一,并负责在其所属的组列中提供其数字响应。因此,对于给定的行,其他2列将为空白。
无论他们属于哪个组,我都需要创建一个包含其得分的列。在Stackoverflow上,我有一个类似的问题,但这是针对Python的(请参见here)
以下是数据的外观以及我所做的事情:
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)])
由于某些行中缺少数据,R错误地将该新列转换为列表。我尝试使用as.data.frame
将其重新转换为数据帧,但是没有用。
请告知如何防止新创建的列变成列表。
答案 0 :(得分:3)
无需使用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
max.col
为我们提供了每行具有最大值的列号索引,由于我们将其包装在!is.na
中,它将为我们提供TRUE
的索引。
max.col(!is.na(df))
#[1] 1 2 2 3 3 1 2
您的apply
不起作用的原因是,您的最后一行具有所有NA
,而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
我们还可以通过删除max
来找出每一行的NA
值,但是对于所有-Inf
的行,这将返回NA
apply(df, 1,max, na.rm = TRUE)
#[1] 13 59 66 23 42 20 -Inf
答案 1 :(得分:2)
基数R rowMeans
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
答案 2 :(得分:1)
如何将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))
结果:
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
另一种选择是使用rowSums
:
df$value <- rowSums(df, na.rm = T)
df[df$value == 0, ] <- NA
从性能角度来看,基本的Reduce
解决方案似乎是最有效的:
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