r - 在多列上使用 ifelse 条件
问题描述
我想生成变量来检查特定事件是否在多个条件下发生。下面是一个示例数据框。
df <- data.frame(
index = c(1:20),
con1 = c(1,3,2,4,2,7,5,9,1,2,5,6,1,0,8,0,4,5,7,3),
con2 = c(3,5,1,6,3,4,7,3,2,1,5,7,9,1,4,2,4,3,4,3),
con3 = c(2,7,3,4,1,9,4,0,7,0,5,2,7,5,9,3,5,2,1,2))
实际数据集有 20 个条件 [con*] 和 10 种不同的事件类型([con*] 中的每个数字。
我现在正在做的是使用这样一个乏味的命令;
df %>% mutate (Event1 = ifelse (con1==1 | con2==1 | con3==1,1,0))
df %>% mutate (Event2 = ifelse (con1==2 | con2==2 | con3==2,1,0))
...
它正是我想要得到的。但是,您可以想象这在脚本中有多少混乱,有 20 个条件和 10 个不同的事件。你知道我怎样才能使它整洁吗?
解决方案
哈克,
library(dplyr)
library(purrr) # map_dfc
events <- setNames(1:4, paste0("Event", 1:4))
df %>%
bind_cols(map_dfc(events, ~ +(rowSums(df[,-1] == .) > 0))) %>%
head()
# index con1 con2 con3 Event1 Event2 Event3 Event4
# 1 1 1 3 2 1 1 1 0
# 2 2 3 5 7 0 0 1 0
# 3 3 2 1 3 1 1 1 0
# 4 4 4 6 4 0 0 0 1
# 5 5 2 3 1 1 1 1 0
# 6 6 7 4 9 0 0 0 1
这在没有purrr::map_dfc
, with 的情况下有效
library(dplyr)
df %>%
bind_cols(lapply(events, function(ev) +(rowSums(df[,-1] == ev) > 0)))
# or even juset
cbind(df, lapply(events, function(ev) +(rowSums(df[,-1] == ev) > 0)))
使用df[,-1]
的前提是您正在处理除第一列之外的所有列。它也可以用一些 tidyverse 动词 ( select(df, starts_with("con"))
) 代替,以达到相同的效果。
这个答案的基本机制是使用rowSums
and ==
。df == ev
返回一个逻辑矩阵。现在有了一个真/假矩阵,我们可以寻找行和,其中 false=0 和 true=1。这样一来,任何大于 0 的总和都意味着至少有一列是正确的。
这+(...)
是将逻辑转换为整数的快速技巧。
推荐阅读
- firebase - SwiftUI Firebase。删除所有项目而不仅仅是一个
- javascript - 对象方法中的 this
- android - 如何从 Delphi 10.3 平台中的 android 设备中检索视频的缩略图?
- excel - 变量范围的总和
- django - Nginx,Django - 域给出 400(错误请求)但通过 IP 地址到达工作
- html - 通过api中的链接重定向到另一个网站
- python - 在 Tkinter 中打开 .py 文件并通过 GUI 提供用户输入
- javascript - 在新选项卡中单击弹出打开链接中的名称时?
- kubernetes - 大使网关:Grafana 在 Kubernetes 环境中无法正确重定向
- flutter - Flutter 中的复选框