在 R 中使用 ifelse 多个条件进行变异
Mutate with ifelse multiple conditions in R
我有如下数据框
monkey = data.frame(girl = 1:10, kn = NA, boy = 5)
而我想一步步理解下面代码的意思
monkey %>%
mutate(t = ifelse(is.na(kn),.[,grepl('a',names(.))],ll))
在此先感谢大家的支持。
在我看来,这不是好的代码,但我会尝试解释它的作用。
is.na(kn)
(在 monkey
的上下文中)returns 该列中的每个值是否为 NA
、[= 的逻辑向量43=]
with(monkey, is.na(kn))
# [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
在.[grepl(*)]
中使用.
指的是本次调用mutate
开始时的当前数据;使用 cur_data()
会更 dplyr-canonical,这将是 more-complete(例如,考虑到 .
不识别的先前变异列,这里不是一个因素)。我相信此 .[*]
代码正在尝试 select 基于当前数据的动态列。
为什么这个不好:
1、这里没有列其名称包含"a"
;
2. 可以有多个名称包含 "a"
的列,这意味着 ifelse
的 yes=
参数将在新的 t=
列中产生一个嵌套框架;
3. 如果原始帧是 base-R data.frame
或 tibble-variant tbl_df
,.[,*]
的行为会改变:参见 monkey[,1]
与tibble(monkey)[,1]
.
no=
参数引用了一个未定义的对象 ll
。这个 应该 (直觉上)失败并显示 Error: object 'll' not found
或类似的,但是由于所有 test=
参数都是真的,所以 no=
是不需要的,所以它没有评估。考虑 ifelse(c(TRUE, TRUE), 1:2, stop("oops"))
(无错误)与 ifelse(c(TRUE, FALSE), 1:2, stop("oops"))
.
最终,此代码不 defensive-enough 是安全的(base-vs-tibble 变体)并且其意图不明确。
我在使用 dplyr
时的建议是使用 dplyr::if_else
而不是基础 R 的 ifelse
。其一,ifelse
有一些问题和限制(例如,How to prevent ifelse() from turning Date objects into numeric objects);另一方面,if_else
保护您免受模棱两可的 inconsistent-results 代码的影响,例如您的问题。
我有如下数据框
monkey = data.frame(girl = 1:10, kn = NA, boy = 5)
而我想一步步理解下面代码的意思
monkey %>%
mutate(t = ifelse(is.na(kn),.[,grepl('a',names(.))],ll))
在此先感谢大家的支持。
在我看来,这不是好的代码,但我会尝试解释它的作用。
is.na(kn)
(在monkey
的上下文中)returns 该列中的每个值是否为NA
、[= 的逻辑向量43=]with(monkey, is.na(kn)) # [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
在
.[grepl(*)]
中使用.
指的是本次调用mutate
开始时的当前数据;使用cur_data()
会更 dplyr-canonical,这将是 more-complete(例如,考虑到.
不识别的先前变异列,这里不是一个因素)。我相信此.[*]
代码正在尝试 select 基于当前数据的动态列。为什么这个不好: 1、这里没有列其名称包含
"a"
; 2. 可以有多个名称包含"a"
的列,这意味着ifelse
的yes=
参数将在新的t=
列中产生一个嵌套框架; 3. 如果原始帧是 base-Rdata.frame
或 tibble-varianttbl_df
,.[,*]
的行为会改变:参见monkey[,1]
与tibble(monkey)[,1]
.no=
参数引用了一个未定义的对象ll
。这个 应该 (直觉上)失败并显示Error: object 'll' not found
或类似的,但是由于所有test=
参数都是真的,所以no=
是不需要的,所以它没有评估。考虑ifelse(c(TRUE, TRUE), 1:2, stop("oops"))
(无错误)与ifelse(c(TRUE, FALSE), 1:2, stop("oops"))
.
最终,此代码不 defensive-enough 是安全的(base-vs-tibble 变体)并且其意图不明确。
我在使用 dplyr
时的建议是使用 dplyr::if_else
而不是基础 R 的 ifelse
。其一,ifelse
有一些问题和限制(例如,How to prevent ifelse() from turning Date objects into numeric objects);另一方面,if_else
保护您免受模棱两可的 inconsistent-results 代码的影响,例如您的问题。