在 case_when 中使用列名作为失败输出
Using a column name as a fail output in case_when
我正在比较从一组文件中提取的几列 ID 变量与主列表,这些 ID 应该跨列匹配。我正在使用 case_when 来确保它们都符合主列表,但我想知道是否有一种方便的方法可以将“TRUE ~”输出更改为未通过测试的值的列名?
这是基本要点,
a <- c(1,2,3,4)
b <- c(1,2,3,4)
c <- c(1,2, "NA", "NA")
d <- c(1,2,3,4)
example <- data.table(a,b,c,d)
example %>% mutate(
test = case_when(
a==b & a==c & a==d ~ "PASS",
TRUE ~ "FAIL")
)
这将完成标记任何未通过测试的值的基本工作,但是是否有一种模块化方法可以将 TRUE ~ "FAIL" 输出更改为产生失败的列的名称,"c" in这种情况?
library(dplyr)
example %>%
rowwise() %>%
dplyr::mutate(cond = cond = names(example)[which(!replace_na(a == c_across(b:d), F)) + 1] %>%
paste(collapse = ",")) %>%
ungroup()
注:+ 1
是因为这个按索引查找列名没有通过。 + 1
是跳过第 a
列,以便 cond
显示正确的列。 paste
用于有多个不满足条件的列。它们将在 cond
.
中以逗号分隔
另外正如@r2evans 在关于强制的评论中提到的,我将 c <- c(1,2, "NA", "NA")
修改为 c <- c(1,2, NA, NA)
。
输出
a b c d cond
<dbl> <dbl> <dbl> <dbl> <chr>
1 1 1 1 1 ""
2 2 2 2 2 ""
3 3 3 NA 3 "c"
4 4 4 NA 4 "c"
多列失败条件
a <- c(1,2,3,4)
b <- c(1,2,3,4)
c <- c(1,2, NA, NA)
d <- c(1,2,3,6)
example <- data.frame(a,b,c,d)
example %>%
rowwise() %>%
dplyr::mutate(cond = cond = names(example)[which(!replace_na(a == c_across(b:d), F)) + 1] %>%
paste(collapse = ",")) %>%
ungroup()
a b c d cond
<dbl> <dbl> <dbl> <dbl> <chr>
1 1 1 1 1 ""
2 2 2 2 2 ""
3 3 3 NA 3 "c"
4 4 4 NA 6 "c,d"
将向量存储在数据框中并使用 sapply
可行:
a <- c(1,2,3,4)
b <- c(1,2,3,4)
c <- c(1,2, "NA", "NA")
d <- c(1,2,3,4)
df <- data.frame(a,b,c,d)
result <- sapply(2:4, function(x) identical(df$a, df[, x]))
result
[1] TRUE FALSE TRUE
您可以根据实际数据框的尺寸调整 sapply
中的参数。您还可以 rbind
result
到 df
并为列 a
:
插入虚拟值
result <- c(999, result)
df <- rbind(result, df)
df
a b c d
1 999 1 0 1
2 1 1 1 1
3 2 2 2 2
4 3 3 NA 3
5 4 4 NA 4
为了类型的完整性,逻辑值 result
被转换为整数。结果行中的零表示哪些列未通过测试。
我正在比较从一组文件中提取的几列 ID 变量与主列表,这些 ID 应该跨列匹配。我正在使用 case_when 来确保它们都符合主列表,但我想知道是否有一种方便的方法可以将“TRUE ~”输出更改为未通过测试的值的列名?
这是基本要点,
a <- c(1,2,3,4)
b <- c(1,2,3,4)
c <- c(1,2, "NA", "NA")
d <- c(1,2,3,4)
example <- data.table(a,b,c,d)
example %>% mutate(
test = case_when(
a==b & a==c & a==d ~ "PASS",
TRUE ~ "FAIL")
)
这将完成标记任何未通过测试的值的基本工作,但是是否有一种模块化方法可以将 TRUE ~ "FAIL" 输出更改为产生失败的列的名称,"c" in这种情况?
library(dplyr)
example %>%
rowwise() %>%
dplyr::mutate(cond = cond = names(example)[which(!replace_na(a == c_across(b:d), F)) + 1] %>%
paste(collapse = ",")) %>%
ungroup()
注:+ 1
是因为这个按索引查找列名没有通过。 + 1
是跳过第 a
列,以便 cond
显示正确的列。 paste
用于有多个不满足条件的列。它们将在 cond
.
另外正如@r2evans 在关于强制的评论中提到的,我将 c <- c(1,2, "NA", "NA")
修改为 c <- c(1,2, NA, NA)
。
输出
a b c d cond
<dbl> <dbl> <dbl> <dbl> <chr>
1 1 1 1 1 ""
2 2 2 2 2 ""
3 3 3 NA 3 "c"
4 4 4 NA 4 "c"
多列失败条件
a <- c(1,2,3,4)
b <- c(1,2,3,4)
c <- c(1,2, NA, NA)
d <- c(1,2,3,6)
example <- data.frame(a,b,c,d)
example %>%
rowwise() %>%
dplyr::mutate(cond = cond = names(example)[which(!replace_na(a == c_across(b:d), F)) + 1] %>%
paste(collapse = ",")) %>%
ungroup()
a b c d cond
<dbl> <dbl> <dbl> <dbl> <chr>
1 1 1 1 1 ""
2 2 2 2 2 ""
3 3 3 NA 3 "c"
4 4 4 NA 6 "c,d"
将向量存储在数据框中并使用 sapply
可行:
a <- c(1,2,3,4)
b <- c(1,2,3,4)
c <- c(1,2, "NA", "NA")
d <- c(1,2,3,4)
df <- data.frame(a,b,c,d)
result <- sapply(2:4, function(x) identical(df$a, df[, x]))
result
[1] TRUE FALSE TRUE
您可以根据实际数据框的尺寸调整 sapply
中的参数。您还可以 rbind
result
到 df
并为列 a
:
result <- c(999, result)
df <- rbind(result, df)
df
a b c d
1 999 1 0 1
2 1 1 1 1
3 2 2 2 2
4 3 3 NA 3
5 4 4 NA 4
为了类型的完整性,逻辑值 result
被转换为整数。结果行中的零表示哪些列未通过测试。