isTRUE和isFALSE在dplyr mutate函数中未按预期工作
我想检查数据帧的两列中的值是否不匹配,并使用此信息创建一个新列。我想使用isTRUE和isFALSE在dplyr mutate函数中未按预期工作,r,dplyr,mutate,R,Dplyr,Mutate,我想检查数据帧的两列中的值是否不匹配,并使用此信息创建一个新列。我想使用dplyr::mutate,并且我想能够处理NA值。使用以下代码可以生成一个简单的示例: library(dplyr) let <- c("a", "b", NA) LET <- c("A") perms <- expand.grid( let_2 = let, LET_2 = LET, let_1 = let, LET_1 = LET, stri
dplyr::mutate
,并且我想能够处理NA
值。使用以下代码可以生成一个简单的示例:
library(dplyr)
let <- c("a", "b", NA)
LET <- c("A")
perms <- expand.grid(
let_2 = let,
LET_2 = LET,
let_1 = let,
LET_1 = LET,
stringsAsFactors = FALSE
) %>%
.[ncol(.):1]
> perms
LET_1 let_1 LET_2 let_2
1 A a A a
2 A a A b
3 A a A <NA>
4 A b A a
5 A b A b
6 A b A <NA>
7 A <NA> A a
8 A <NA> A b
9 A <NA> A <NA>
我认为下面的代码应该可以工作,但它给出了以下输出:
good_perms1 <- perms %>%
dplyr::mutate(LET_mismatch = !isTRUE(LET_1 == LET_2)) %>%
dplyr::mutate(let_mismatch = !isTRUE(let_1 == let_2))
> good_perms1
LET_1 let_1 LET_2 let_2 LET_mismatch let_mismatch
1 A a A a TRUE TRUE
2 A a A b TRUE TRUE
3 A a A <NA> TRUE TRUE
4 A b A a TRUE TRUE
5 A b A b TRUE TRUE
6 A b A <NA> TRUE TRUE
7 A <NA> A a TRUE TRUE
8 A <NA> A b TRUE TRUE
9 A <NA> A <NA> TRUE TRUE
我意识到这里可能有三个问题,但第一个是我最困惑的问题:
dplyr::mutate
评估!两个的isTRUE
到TRUE
!isTRUE(“a”==“a”)
和!isTRUE(“a”==“b”)
?类似地,isFALSE
NA==“a”
识别为FALSE
和NA==NA
识别为TRUE
NA
s的问题可能需要单独解决,我现在最关心的是为什么!isTRUE
在dplyr::mutate
中的行为与预期不符。谢谢
p.S.涉及到这个问题,但通过不同的方式解决了。也许可以将
NA
替换为字符“NA”,运行您的代码,然后将字符“NA”替换回NA
library(dplyr)
good_perms2 <- perms %>%
mutate_all(list(~replace(., is.na(.), "NA"))) %>%
mutate(LET_mismatch = (LET_1 != LET_2)) %>%
mutate(let_mismatch = (let_1 != let_2)) %>%
mutate_all(list(~replace(., . %in% "NA", NA_character_)))
good_perms2
# LET_1 let_1 LET_2 let_2 LET_mismatch let_mismatch
# 1 A a A a FALSE FALSE
# 2 A a A b FALSE TRUE
# 3 A a A <NA> FALSE TRUE
# 4 A b A a FALSE TRUE
# 5 A b A b FALSE FALSE
# 6 A b A <NA> FALSE TRUE
# 7 A <NA> A a FALSE TRUE
# 8 A <NA> A b FALSE TRUE
# 9 A <NA> A <NA> FALSE FALSE
库(dplyr)
良好的perms2%
突变所有(列表(~replace(,is.na(.),“na”))%>%
突变(LET_失配=(LET_1!=LET_2))%>%
突变(let_失配=(let_1!=let_2))%>%
变异所有(列表(~replace(,.%在%“NA”,NA_字符中)))
祝你好运
#让\u 1让\u 1让\u 2让\u不匹配让\u不匹配
#一个假的假的
#2 A b假-真
#3是假是真
#4 A b A A假真
#5 A b b错误-错误
#是假是真
#虚假的事实
#8 A b假真
#9 A是假的
您遇到此问题是因为isTRUE
和isFALSE
不是矢量化函数。根据?isTRUE
:
isTRUE(x)与{is.logical(x)&&length(x)==1&&!is.na(x)&&x}相同;isFALSE()的定义与此类似。因此,由于NAs的原因,if(isTRUE(cond))可能比if(cond)更可取
知道我刚才展示的内容,让我们看看你们的问题
case\u when()
解决方案
library(dplyr)
good_perms1 <- perms %>%
mutate(LET_mismatch = case_when(
LET_1 == LET_2 ~ FALSE,
is.na(LET_1) & is.na(LET_2) ~ FALSE,
TRUE ~ TRUE),
let_mismatch = case_when(
let_1 == let_2 ~ FALSE,
is.na(let_1) & is.na(let_2) ~ FALSE,
TRUE ~ TRUE))
good_perms1
#> LET_1 let_1 LET_2 let_2 LET_mismatch let_mismatch
#> 1 A a A a FALSE FALSE
#> 2 A a A b FALSE TRUE
#> 3 A a A <NA> FALSE TRUE
#> 4 A b A a FALSE TRUE
#> 5 A b A b FALSE FALSE
#> 6 A b A <NA> FALSE TRUE
#> 7 A <NA> A a FALSE TRUE
#> 8 A <NA> A b FALSE TRUE
#> 9 A <NA> A <NA> FALSE FALSE
库(dplyr)
良好的绩效1%
变异(假设不匹配=情况)(
设_1==设_2~为FALSE,
is.na(LET_1)&is.na(LET_2)~FALSE,
真~真),
当(
设_1==设_2~为FALSE,
is.na(let_1)&is.na(let_2)~FALSE,
真~真)
祝你好运
#>让\u 1让\u 1让\u 2让\u不匹配让\u不匹配
#>一个假的假的
#>2 A b假-真
#>3是假是真
#>4 A b A A假真
#>5 A b b错误-错误
#>是假是真
#>虚假的事实
#>8 A b假真
#>9 A是假的
添加rowwise()
good_perms1%rowwise()%%>%
dplyr::mutate(LET_mismatch=!isTRUE(LET_1==LET_2))%>%
dplyr::mutate(let_mismatch=!isTRUE(let_1==let_2))
看看首先给出的是什么(perms$let\u 1==perms$let\u 2)<代码>isTRUE
不是由它的外观矢量化的。从?isTRUE
“'isTRUE(x)'是'idential(TRUE,x)'的缩写,当且仅当'x'是长度为1的逻辑向量时,也是如此”我不能复制你的1“。查询任何一个-!isTRUE(“a”==“a”)
在的同时给出FALSE
!isTRUE(“a”==“b”)
给出了TRUE
@最近的邮件,关于你的第二点,我应该说“从dplyr::mutate
”内部。关于你的第一点,我认为变异评估!isTRUE(perms$let_1[1]==perms$let_2[1]
然后计算!isTRUE(perms$let_1[2]==perms$let_2[1]
,但你让我意识到变异会评估!isTRUE(perms$let_1==perms$let_2
。我需要编写一个isTRUE
的矢量化版本,处理我对NA
的具体标准。谢谢。将NA
转换为“NA”
比我要编写的复杂更容易。NA
函数。谢谢!mutate\u all(~replace(,.is.na(,.is.na(,.na))
似乎有效。是否有必要使用mutate\u all(list(~replace(,.is.na(,.is.na(,“na”))
)的用例来替换所有(list(,.is.na(,“na”)
)
。这将非常有用。谢谢!您可以创建一个函数f1%mutate(LET\u mismatch=f1(LET\u 1,LET\u 2),LET\u misch=f1(LET\u 1,LET\u 2))
good_perms2 <- perms %>%
dplyr::mutate(LET_mismatch = (LET_1 != LET_2)) %>%
dplyr::mutate(let_mismatch = (let_1 != let_2))
> good_perms2
LET_1 let_1 LET_2 let_2 LET_mismatch let_mismatch
1 A a A a FALSE FALSE
2 A a A b FALSE TRUE
3 A a A <NA> FALSE NA
4 A b A a FALSE TRUE
5 A b A b FALSE FALSE
6 A b A <NA> FALSE NA
7 A <NA> A a FALSE NA
8 A <NA> A b FALSE NA
9 A <NA> A <NA> FALSE NA
library(dplyr)
good_perms2 <- perms %>%
mutate_all(list(~replace(., is.na(.), "NA"))) %>%
mutate(LET_mismatch = (LET_1 != LET_2)) %>%
mutate(let_mismatch = (let_1 != let_2)) %>%
mutate_all(list(~replace(., . %in% "NA", NA_character_)))
good_perms2
# LET_1 let_1 LET_2 let_2 LET_mismatch let_mismatch
# 1 A a A a FALSE FALSE
# 2 A a A b FALSE TRUE
# 3 A a A <NA> FALSE TRUE
# 4 A b A a FALSE TRUE
# 5 A b A b FALSE FALSE
# 6 A b A <NA> FALSE TRUE
# 7 A <NA> A a FALSE TRUE
# 8 A <NA> A b FALSE TRUE
# 9 A <NA> A <NA> FALSE FALSE
x <- "a" == "a" # TRUE
y <- "a" == "b" # FALSE
!isTRUE(x)
#> [1] FALSE
!isTRUE(y)
#> [1] TRUE
!(is.logical(x) && length(x) == 1 && !is.na(x) && x)
#> [1] FALSE
!(is.logical(y) && length(y) == 1 && !is.na(y) && y)
#> [1] TRUE
let_1 <- c("a", "a", "a", "b", "b", "b", NA, NA, NA)
let_2 <- c("a", "b", NA, "a", "b", NA, "a", "b", NA)
let_1 == let_2
#> [1] TRUE FALSE NA FALSE TRUE NA NA NA NA
!isTRUE(let_1 == let_2)
#> TRUE
x <- (let_1 == let_2)
!(is.logical(x) && length(x) == 1 && !is.na(x) && x)
#> TRUE
library(dplyr)
foo <- function(x, y) {
case_when(
is.na(x) & !is.na(y) ~ FALSE,
is.na(x) & is.na(y) ~ TRUE)
}
foo(NA, "a")
#> [1] FALSE
foo(NA, NA)
#> [1] TRUE
library(dplyr)
good_perms1 <- perms %>%
mutate(LET_mismatch = case_when(
LET_1 == LET_2 ~ FALSE,
is.na(LET_1) & is.na(LET_2) ~ FALSE,
TRUE ~ TRUE),
let_mismatch = case_when(
let_1 == let_2 ~ FALSE,
is.na(let_1) & is.na(let_2) ~ FALSE,
TRUE ~ TRUE))
good_perms1
#> LET_1 let_1 LET_2 let_2 LET_mismatch let_mismatch
#> 1 A a A a FALSE FALSE
#> 2 A a A b FALSE TRUE
#> 3 A a A <NA> FALSE TRUE
#> 4 A b A a FALSE TRUE
#> 5 A b A b FALSE FALSE
#> 6 A b A <NA> FALSE TRUE
#> 7 A <NA> A a FALSE TRUE
#> 8 A <NA> A b FALSE TRUE
#> 9 A <NA> A <NA> FALSE FALSE
good_perms1 <- perms %>% rowwise() %>%
dplyr::mutate(LET_mismatch = !isTRUE(LET_1 == LET_2)) %>%
dplyr::mutate(let_mismatch = !isTRUE(let_1 == let_2))