Как изменить новые столбцы во всех комбинациях других столбцов?

#r #dplyr #across

#r #dplyr #через

Вопрос:

Моя отправная точка — данные вигов из пакета ggraph. Он содержит матрицу инцидентности.

Теперь, для каждой комбинации столбцов / переменных, я хотел бы знать, все ли столбцы равны 1 или нет, и создать новый столбец для этой комбинации с 1, если действительно все столбцы равны 1 или 0, если нет.

Данные вигов — это всего лишь пример: я ищу векторизованный метод, который можно использовать независимо от количества столбцов / комбинаций.

Используя dplyr, я могу использовать across() mutate() функцию in для создания нескольких новых столбцов, но я не могу понять, как создать эти столбцы на основе различных комбинаций столбцов.

Также, используя dplyr, я могу использовать c_across() mutate() функцию in в сочетании с rowwise() функцией для создания одного нового столбца на основе значений в нескольких столбцах.

Может быть, эти два можно как-то объединить?

Ответ №1:

Вы могли бы попробовать

 library(dplyr)
df <- data.frame(A = rep(0, 4), 
                 B = c(1, 0, 0, 1), 
                 C = c(0, 1, 1, 0), 
                 D = c(0, 1, 1 ,1))
cols  <- 1:ncol(df)

combs  <- unlist(sapply(cols[-1], function(x) {
  asplit(combn(cols, m = x), 2)
}), recursive = FALSE)

lapply(combs, function(x) {
  df <<- df %>% mutate(!!paste0(x, collapse = "/") := as.numeric(rowSums(df[, x]) == length(x))) 
})
 

Мы создаем все комбинации столбцов по индексу и применяем к каждой комбинации функцию, которая проверяет, все ли значения этих столбцов равны 1, проверяя сумму строк. Если это так, мы добавляем новый столбец с именем «x / y / z …», где x, y и z — индексы сравниваемых столбцов, которые равны 1, а остальное 0.
Осторожно, это довольно дорого, когда количество столбцов растет.

   A B C D 1/2 1/3 1/4 2/3 2/4 3/4 1/2/3 1/2/4 1/3/4 2/3/4 1/2/3/4
1 0 1 0 0   0   0   0   0   0   0     0     0     0     0       0
2 0 0 1 1   0   0   0   0   0   1     0     0     0     0       0
3 0 0 1 1   0   0   0   0   0   1     0     0     0     0       0
4 0 1 0 1   0   0   0   0   1   0     0     0     0     0       0
 

Комментарии:

1. Спасибо, Мартин! По какой-то причине он не возвращает 1, если оба столбца содержат 1. И я хотел бы сделать это для всех комбинаций столбцов, включая комбинации от 3 до n столбцов. Как мне пройти через все комбинации без необходимости перебирать combn(cols, m), где m равно 2: n ?

2. Ах, я вас неправильно понял. Я исправил это. Стало немного уродливее 🙂