一些选项:
df <- read.table(text = 'var1 var2 var3
m01 Y NA
m02 Y NA
m03 NA Y
m04 NA Y
m05 Y Y
m06 Y NA
m07 Y Y', head = TRUE, stringsAsFactors = FALSE)
典型的基本 R 方法是 apply 在必要的列中逐行迭代。这是在默默地强制转换为矩阵,这就是为什么有些人会避免这种方法。
apply(df[-1], 1, function(x){sum(which(x == 'Y'))})
#> [1] 1 1 2 2 3 1 3
您可以使用 rowwise 将其转换为 dplyr,它不会强制转换为矩阵,但通常不是最快的方法:
library(dplyr)
df %>%
rowwise() %>%
mutate(var4 = sum(which(c(var2, var3) == 'Y')))
#> Source: local data frame [7 x 4]
#> Groups: <by row>
#>
#> # A tibble: 7 x 4
#> var1 var2 var3 var4
#> <chr> <chr> <chr> <int>
#> 1 m01 Y <NA> 1
#> 2 m02 Y <NA> 1
#> 3 m03 <NA> Y 2
#> 4 m04 <NA> Y 2
#> 5 m05 Y Y 3
#> 6 m06 Y <NA> 1
#> 7 m07 Y Y 3
对于因子(通过c 将其转换为整数),这也将失败,但可以预先或在内部强制它们,或者您可以使用is.na 而不是检查相等性。
更多创造性的基本选项包括将列粘贴在一起以创建一个可以故意平衡以强制转换为整数的因子:
as.integer(factor(paste0(df$var2, df$var3), levels = c('YNA', 'NAY', 'YY')))
#> [1] 1 1 2 2 3 1 3
或使用do.call 将函数列表和df 的每个所需变量(用c 展平)传递给mapply:
do.call(mapply,
c(function(...){sum(which(!is.na(c(...))))},
df[-1],
USE.NAMES = FALSE))
#> [1] 1 1 2 2 3 1 3
如果你真的想要 ifelse 逻辑,dplyr::case_when 让你可以使用级联条件句,而不会使用混乱的语法:
df %>% mutate(var4 = case_when(var2 == 'Y' & var3 == 'Y' ~ 3,
var2 == 'Y' ~ 1,
var3 == 'Y' ~ 2))
#> var1 var2 var3 var4
#> 1 m01 Y <NA> 1
#> 2 m02 Y <NA> 1
#> 3 m03 <NA> Y 2
#> 4 m04 <NA> Y 2
#> 5 m05 Y Y 3
#> 6 m06 Y <NA> 1
#> 7 m07 Y Y 3