当Q7
和Q8
都缺失时,可以使用ifelse()
来判断条件.如果为真,则结果为1,否则将值保持在Q7
.下面的代码就是这样做的.注意,您发布的数据没有任何这样的条目,所以我将第二个观察值的Q7
值更改为NA
,您可以在结果中看到它更改为1.
dat <- read.table(textConnection("Q7 Q8
NA 1
1 NA
NA NA
1 NA
NA NA
NA 1
1 NA
NA 1
1 NA
1 NA"), header=TRUE)
dat$Q7 <- ifelse(is.na(dat$Q7) & is.na(dat$Q8), 1, dat$Q7)
dat
#> Q7 Q8
#> 1 NA 1
#> 2 1 NA
#> 3 1 NA
#> 4 1 NA
#> 5 1 NA
#> 6 NA 1
#> 7 1 NA
#> 8 NA 1
#> 9 1 NA
#> 10 1 NA
创建于2023-05-03年第reprex v2.0.2页
Speed Benchmarks
comments 中有一些关于速度的讨论.以下是提出的不同方法的基准.不足为奇的是,这里的dplyr
管道速度要慢一些.我的经验是,他们的dplyr
对于小问题来说是慢的,对于大问题来说是快的(尽管在任何特定的情况下都是YMMV).这两种基本的方法彼此没有明显的区别,尽管ifelse()
略有优势.
library(microbenchmark)
microbenchmark(
"ifelse_baseR" = {dat$Q7 <- ifelse(is.na(dat$Q7) & is.na(dat$Q8), 1, dat$Q7)},
"rowSums_baseR" = {dat[rowSums(is.na(dat)) == 2, 'Q7'] <- 1},
"dplyr1" = {dat <- dat %>% mutate(Q7b = if_else(rowSums(!is.na(cbind(Q7, Q8))) == 0, 1, Q7))},
"dplyr2" = {dat <- dat %>% mutate(Q7 = ifelse(rowSums(is.na(.)) == ncol(.), 1, Q7))}
)
#> Warning in microbenchmark(ifelse_baseR = {: less accurate nanosecond times to
#> avoid potential integer overflows
#> Unit: microseconds
#> expr min lq mean median uq max neval cld
#> ifelse_baseR 5.863 7.4210 9.48658 9.7580 10.9470 14.391 100 a
#> rowSums_baseR 12.423 14.5755 18.33192 18.7575 20.2540 33.948 100 a
#> dplyr1 762.067 778.2620 898.97338 799.7665 842.2015 7422.886 100 b
#> dplyr2 664.692 691.5060 783.42718 704.4825 757.5980 2851.222 100 b
创建于2023-05-03年第reprex v2.0.2页