假设我有一个数据框,其中包含三个变量,我想添加第四个变量,其值基于第二个和第三个变量的值,例如。如果var2 = var3则var4 = 3,如果var2 = Y且var3 = NA则var4 = 1,如果var2 = NA且var3 = Y则var4 = 2.
var1 var2 var3
m01 Y NA
m02 Y NA
m03 NA Y
m04 NA Y
m05 Y Y
m06 Y NA
m07 Y Y
我想得到一个这样的数据框:
var1 var2 var3 var4
m01 Y NA 1
m02 Y NA 1
m03 NA Y 2
m04 NA Y 2
m05 Y Y 3
m06 Y NA 1
m07 Y Y 3
我正在尝试ifelse
,但我没有成功。
有什么想法吗?
答案 0 :(得分:6)
每个人都忘记了可怜的旧interaction
:
c(3,2,1,4)[interaction(lapply(dat[-1], is.na))]
#[1] 1 1 2 2 3 1 3
答案 1 :(得分:2)
试试这个:
library(dplyr)
df <- data.frame(var1 = paste0("m0",1:7),
var2 = c(rep("Y",2) ,rep(NA, 2), rep("Y", 3)),
var3 = c(rep(NA, 2), rep("Y", 3), NA, "Y"))
mutate(df, var4 = if_else(var2 == "Y",
if_else(var3 == "Y", 3, 1,1),
2, 2))
来自if_else
包的 dplyr
将处理缺少号码(NA)的情况
答案 2 :(得分:1)
一些选项:
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
而不是检查相等。< / p>
更多创意基本选项包括将列粘贴在一起以创建一个可以故意调整为强制到整数的因子:
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
答案 3 :(得分:1)
使用ifelse:
df$var4 <- ifelse(df$var2 == df$var3, 3,
ifelse(df$var3 == "NA" & df$var2 == "y", 1,
ifelse(df$var2 == "NA" & df$var3 == "y", 2, "?")))
如果“NA”是因子值,则有效。否则,将df$var3 == "NA"
替换为is.na(df$var3)
,将df$var2 == "NA"
替换为is.na(df$var2)