r - 您如何评估一组条件并根据列列表创建新列?
问题描述
我想在数据框中列出(或过滤)一组类似命名的列,为每一行评估这些列的值,然后用结果创建一个新列。
现在我正在使用case_when
,但我不知道提供一些通配符或已定义列的列表的方法。
我想列一个列表或创建一个过滤器,因为我想评估数据框中的几列,而不仅仅是少数。case_when
当列名彼此非常相似时,拥有一长串列似乎效率不高。
# Dummy data
ignore1 <- c(1, 0, 0)
ignore2 <- c(1, 0, 1)
col1 <- c(0, 1, 0)
col2 <- c(0, 1, 1)
col3 <- c(0, 1, 0)
df <- data.frame(ignore1, ignore2, col1, col2, col3)
df %>%
mutate(evaluation = case_when(
col1 == 0| col1 == 0 | col1 == 0 ~ "Failed",
TRUE ~ "Passed"
)
)
这是预期的结果:
ignore1 ignore2 col1 col2 col3 evaluation
1 1 1 0 0 0 Failed
2 0 0 1 1 1 Passed
3 0 1 0 1 0 Failed
其中第 2 行通过,因为,col1
都具有的值。col2
col3
1
解决方案
我们可以用它rowSums
来提高效率
i1 <- startsWith(names(df), 'col')
c( "Failed", "Passed")[(rowSums(df[i1] == 1) == 3) + 1]
#[1] "Failed" "Passed" "Failed"
或者另一个base R
有效的选择是Reduce
c("Failed", "Passed")[Reduce(`&`, df[i1]) +1]
#[1] "Failed" "Passed" "Failed"
注意:两种base R
解决方案都很紧凑并且非常高效
或与&
library(dplyr)
df %>%
mutate(evaluation = c('Failed', 'Passed')[1 + (col1 & col2 & col3)])
# ignore1 ignore2 col1 col2 col3 evaluation
#1 1 1 0 0 0 Failed
#2 0 0 1 1 1 Passed
#3 0 1 0 1 0 Failed
或者我们可以rowSums
在dplyr
df %>%
mutate(evaluation = c("Failed", "Passed")[(rowSums(.[i1] == 1) == 3) + 1])
注意:这两种解决方案都非常有效,并且不使用任何不需要的包
或者如果我们需要一些包,那么使用magrittr
withpurrr
library(magrittr)
library(purrr)
df %>%
mutate(evaluation = select(., starts_with('col')) %>%
reduce(`&`) %>%
add(1) %>%
c("Failed", "Passed")[.])
# ignore1 ignore2 col1 col2 col3 evaluation
#1 1 1 0 0 0 Failed
#2 0 0 1 1 1 Passed
#3 0 1 0 1 0 Failed
注意:在这里,我们也没有循环遍历行,所以它应该是有效的
推荐阅读
- java - 如何恢复 JTable 中的列宽?
- docker - 在 Docker 中的 Python Slim 映像中安装 GDB
- java - 从 .java 文件中获取方法作为文件
- jenkins - 如何通过命令行运行黄瓜标签/步骤定义?
- nginx - Ubuntu 对网络处理的限制
- php - DateTime::createFromFormat 返回 False - 毫秒
- python - 在 Python 3.8 和 xlsxwriter 中写入输出时,特殊字符(é、ê 等)将无法正确显示
- android - Jetpack 版本的 android.support
- kubernetes - 使用 PVC 的 K8s 和守护进程
- python - 带有 if 语句的 Python 文件重命名器