Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 使用“应用”从每行使用非空值创建一个新列_R_Dplyr_Apply - Fatal编程技术网

R 使用“应用”从每行使用非空值创建一个新列

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

我有一个由3列组成的数据框,每列代表受访者所属的组。受访者属于其中一个群体,他们的任务是在他们所属的群体栏中提供他们的数字回答。因此,对于给定的行,另外两列将为空

我需要创建一个列来记录他们的分数,不管他们属于哪个组。关于Stackoverflow,有一个与我类似的问题,但它是针对Python的(请参阅)

以下是数据的外观以及我所做的工作:

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 

基本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
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