В base R
мы используем grep
для подстановки столбцов, начинающихся с «ACT» (или startsWith
), проверяем, равно ли оно «DBA» для создания логической матрицы, затем получаем rowSums
, преобразовать его в логический vector
, проверив количество ИСТИННЫХ элементов больше 0. Этот логический вектор преобразуется в двоичный файл с as.integer
(или +
)
df$newCol <- +(rowSums(df[grep("^ACT", names(df))] == "DBA") > 0)
df$newCol
#[1] 1 1 0
Или другой base R
подход будет использовать Reduce
с lapply
df$newCol <- +(Reduce(`|`, lapply(df[grep("^ACT", names(df))], `==`, "DBA")))
ПРИМЕЧАНИЕ: оба решения векторизованы
Или используя tidyverse
без изменения формы
library(tidyverse)
df %>%
mutate(newCol = map(., ~.x == "DBA") %>%
reduce(`|`) %>%
as.integer)
# ACT_1 ACT_2 ACT_3 ACT_4 ACT_5 ACT_6 ACT_7 newCol
#1 DBA ABC ABC ABC ABC ABC ABC 1
#2 ABC DBA ABC ABC ABC ABC ABC 1
#3 ABC ABC ABC ABC ABC ABC ABC 0
или используя data.table
library(data.table)
setDT(df)[, newCol := +(Reduce(`+`, lapply(.SD, `==`, "DBA")))]
В этом примере есть только столбцы «ACT». Если есть другие столбцы, обязательно укажите .SDcols
с grep
, как показано в первом решении
Тесты
#data
df1 <- df[rep(seq_len(nrow(df)), 1e6), ]
на базе R
system.time(+(rowSums(df1[grep("^ACT", names(df1))] == "DBA") > 0))
# user system elapsed
# 0.319 0.101 0.419
system.time(+(Reduce(`|`, lapply(df1[grep("^ACT", names(df1))], `==`, "DBA"))))
# user system elapsed
# 0.152 0.029 0.179
system.time(as.integer(apply(df1[grep("^ACT", names(df1))] == "DBA", 1, any)))
# user system elapsed
# 5.200 0.177 5.344
-tidyverse
system.time({df1 %>%
mutate(row = row_number()) %>%
gather(key, value, starts_with("ACT")) %>%
group_by(row) %>%
mutate(flag = as.integer(any(value == "DBA"))) %>%
spread(key, value) %>%
ungroup() %>%
select(-row)})
# user system elapsed
# 42.750 4.378 47.202
system.time({
df1 %>%
mutate(newCol = map(., ~.x == "DBA") %>%
reduce(`|`))
})
# user system elapsed
# 0.188 0.016 0.203
-data.table
system.time({
setDT(df1)[, newCol := +(Reduce(`+`, lapply(.SD, `==`, "DBA")))]
})
# user system elapsed
# 0.152 0.011 0.163