2017-01-30 2 views
1

Я хочу рассчитать комбинацию «и» между каждым столбцом, кроме первого столбца id. Я достиг этого через два для циклов. Однако, если для большого размера столбцов и строк следующий метод становится очень медленным. Есть ли эффективное для такогоR: Эффективный метод вычисления логики И среди столбцов

library(dplyr) 
Input <- data_frame(id=1:4, c1=c(T,T,F,F), c2=c(T,F,F,F),c3=c(F,T,F,F)) 
    id c1 c2 c3 
    1 1 TRUE TRUE FALSE 
    2 2 TRUE FALSE TRUE 
    3 3 FALSE FALSE FALSE 
    4 4 FALSE FALSE FALSE 

требуемого выхода:

> Output 
    id c1_c2 c1_c3 c2_c3 
    1 1 TRUE FALSE FALSE 
    2 2 FALSE TRUE FALSE 
    3 3 FALSE FALSE FALSE 
    4 4 FALSE FALSE FALSE 

для цикла подход:

Output <- data_frame(id=Input$id) 
colSize <- ncol(Input) 
colnms <- colnames(Input) 
for(i in 2:(colSize-1)){ 
for (j in (i+1):colSize){ 
    name_i <- paste(colnms[i],colnms[j],sep="_") 
    logic_and <- (Input[colnms[i]]&Input[colnms[j]]) 
    Output$name <- logic_and 
    names(Output)[ncol(Output)] <- name_i 
    } 
} 

ответ

2

Одним из вариантов являются combn от base R

Input[-1] <- do.call(cbind, combn(Input[-1], 2, FUN = function(x) list(x[1] & x[2]))) 
names(Input)[-1] <- combn(names(Input)[-1], 2, FUN = paste, collapse="-") 
Input 
# A tibble: 4 × 4 
#  id `c1-c2` `c1-c3` `c2-c3` 
# <int> <lgl> <lgl> <lgl> 
#1  1 TRUE FALSE FALSE 
#2  2 FALSE TRUE FALSE 
#3  3 FALSE FALSE FALSE 
#4  4 FALSE FALSE FALSE 
+0

привет @ akrun, combn хорошо работает. знаете ли вы, как избежать столбца ci_cj, если все являются ЛОЖНЫМИ? – HappyCoding

+0

@HappyCoding Вы можете использовать 'm1 <- do.call (cbind, combn (Input [-1], 2, FUN = function (x) {i1 <- x [1] & x[2]; colnames (i1) <- paste (имена (x [1]), имена (x [2]), sep = "_"); list (if (any (i1)) i1 else NULL)})) ' – akrun

+1

спасибо. добавление NULL-работ – HappyCoding