首页 > 解决方案 > R函数来识别条件在n列中的任何一个中满足x次的情况?

问题描述

我有一个数据框,我想在其中识别给定条件在一组列中至少满足一定次数的情况(行)。在下面的玩具示例中,我想确定“A”是三列中的两列(Choice_1 到 Choice_3)的选择的情况。我不在乎在三列“A”中的哪两列中找到。在我的示例中,将识别 ID = 1 和 ID = 4。

这应该适用于任意数量的列中所需的任意数量的“A”(例如,如果我想确定“A”是四个选择列中的三个中的选择的情况,则只会识别 ID = 1)。

ID <- 1:4
Choice_1 <- c("A", "B", "C", "D")
Choice_2 <- c("A", "D", "C", "A")
Choice_3 <- c("A", "C", "A", "A")
Choice_4 <- c("B", "B", "A", "B")

df <- data.frame(ID, Choice_1, Choice_2, Choice_3, Choice_4)

> df
ID Choice_1 Choice_2 Choice_3 Choice_4
 1        A        A        A        B
 2        B        D        C        B
 3        C        C        A        A
 4        D        A        A        B

一种迂回的方法是将“A”转换为 1,将所有其他转换为 0,对我感兴趣的选择列求和并检查总和是否等于或高于我的阈值,但我觉得必须成为更好的方法。

按照我的想象,它将是某种形式的 if_else 语句包含在一个 mutate 中,因此符合条件的行将被标识为 1,而那些不符合条件的行将被标识为 0:

df %>% mutate(cond_matched = if_else( two of (Choice_1, Choice_2, Choice_3) == "A", 1, 0))

ID Choice_1 Choice_2 Choice_3 Choice_4 cond_matched
 1        A        A        A        B            1
 2        B        D        C        B            0
 3        C        C        A        A            0
 4        D        A        A        B            1

我希望我只是用错误的关键字搜索。感谢您的任何帮助!

标签: rdplyrtidyr

解决方案


一个基本的 R 选项将是从选定df[2:4] == "A"的列as.integer+

df$cond_matched <- +(rowSums(df[2:4] == "A") >= 2)
df$cond_matched
#[1] 1 0 0 1

或使用tidyverse(使用来自基本 R 解决方案的类似逻辑,但语法不完全相同)

library(tidyverse)
df %>% 
    mutate(cond_matched = select(., 2:4) %>%
                            map(~ .x == 'A') %>%
                            reduce(`+`) %>%
                            `>=`(2) %>% 
                            as.integer)
#   ID Choice_1 Choice_2 Choice_3 Choice_4 cond_matched
#1  1        A        A        A        B            1
#2  2        B        D        C        B            0
#3  3        C        C        A        A            0
#4  4        D        A        A        B            1

推荐阅读