2016-06-22 3 views
2

에서 바로 기능을 "..."인수에서 내가 범주와 연속 변수 모두의 행렬의 상관 관계를 계산하는 기능이 있습니다주기 인수 R

correlation <- function(matrix, ...) { 
    xx <- do.call(rbind, lapply(colnames(mtrc), function(ex_i) { 
     ty_i <- wtype(matrix, ex_i) 
     yy <- sapply(colnames(mtrc), function(ex_j) { 
      ty_j <- wtype(matrix, ex_j) 

      if(ty_i == "numeric" & ty_j == "numeric") { 
       cor(mtrc[ , c(ex_i, ex_j)], ...)[1, 2] 
      } else if(ty_i == "factor" & ty_j == "factor") { 
       cramersV(table(mtrc[ , c(ex_i, ex_j)]), ...) 
      } else { 
       fm <- paste(ex_i, "~", ex_j) 
       if(ty_i == "factor") { 
        fm <- paste(ex_j, "~", ex_i) 
       } 
       fm <- lm(fm, data = mtrc[ , c(ex_i, ex_j)], ...) 
       lm.beta(fm) 
      } 
     }) 
     names(yy) <- colnames(mtrc) 
     yy 
    })) 
    rownames(xx) <- colnames(mtrc) 
    xx 
} 

내 질문이 제대로 전달하는 방법이다, 인수는 ...에서 cor, cramerVlm입니다. 사용자가 cor에 대한 인수를 제공하고 행렬에 범주 형 변수가있는 경우 인수의 이름이 일치하지 않으므로 cramerV 또는 lm은 오류 (사용되지 않은 인수 ...)를 발생시킵니다.

그래서 ... 나는 당신이 가질 수있는 모든 해결책이나 아이디어에 열려 있습니다.

+2

'dots <- list (...)'를 실행하고 어떤 요소가'formalArgs (lm) '과 일치하는지 확인하고 목록을 이들에 부분 집합하십시오. 이 목록에'fm'과'data' 매개 변수를 추가하고'do.call'을 사용하여'lm'을 호출하십시오. 나는 당신에게 어떻게 보여줄 것이지만 재현 가능한 예를 제공하지는 않습니다. – Roland

+0

'pryr' 패키지에서'dots' 또는'named_dots' 함수를 찾을 수 있습니다. –

답변

2

2014 년에 Richard Scriven이 훌륭한 질문을했다는 것을 깨닫지 못했습니다. Split up `...` arguments and distribute to multiple functions, 아래에서 답을 만들었습니다. 그래서 네, 이것은 이중화 된 질문입니다. 그러나 내가 생각한 것을 (그리고 내가 생각하는대로) 표현하기 때문에 나는 여기서 나의 대답을 지킬 것입니다.


원래 대답

나는 이것이 당신의 correlation 기능 미세한 제어함으로써, 더 나은 생각 : 당신은 cor.opt 인수를 통해 다른 기능을위한 다른 인수를 전달할 수 있습니다

correlation <- function(matrix, cor.opt = list(), cramersV.opt = list(), lm.opt = list()) { 
    xx <- do.call(rbind, lapply(colnames(mtrc), function(ex_i) { 
     ty_i <- wtype(matrix, ex_i) 
     yy <- sapply(colnames(mtrc), function(ex_j) { 
      ty_j <- wtype(matrix, ex_j) 

      if(ty_i == "numeric" & ty_j == "numeric") { 
       do.call("cor", c(list(x = mtrc[ , c(ex_i, ex_j)]), cor.opt))[1, 2] 
      } else if(ty_i == "factor" & ty_j == "factor") { 
       do.call("cramersV", c(list(x = table(mtrc[ , c(ex_i, ex_j)])), cramersV.opt)) 
      } else { 
       fm <- paste(ex_i, "~", ex_j) 
       if(ty_i == "factor") { 
        fm <- paste(ex_j, "~", ex_i) 
       } 
       fm <- do.call("lm", c(list(formula = fm, data = mtrc[ , c(ex_i, ex_j)]), lm.opt)) 
       lm.beta(fm) 
      } 
     }) 
     names(yy) <- colnames(mtrc) 
     yy 
    })) 
    rownames(xx) <- colnames(mtrc) 
    xx 
} 

을, cramersV.optlm.opt. 그런 다음 함수 correlation 안에 모든 관련 함수 호출에 do.call()을 사용하십시오.


코멘트

내가 좋아 @ 롤랜드의 생각. 그는 ...을 사용하고 다른 기능의 공식 인수에 따라 list(...)을 분리합니다. 다른 한편으로, 저는 여러분에게 수동으로 그러한 인수를 다른 목록에 지정하도록 요청했습니다. 결국 우리 둘다 함수 호출에 do.call()을 사용할 것을 요청합니다.

...이 필요한 더 많은 기능으로 확장하기가 쉽기 때문에 롤랜드의 아이디어가 광범위하게 적용됩니다.