2012-06-08 4 views
4

예를 들어, I는 매트릭스를 가지고 kR에서 적용을 사용할 때 현재 행의 이름을 인쇄하는 방법은 무엇입니까?

> k 
    d e 
a 1 3 
b 2 4 

제가 또한 그렇게 apply되는 행의 rowname를 인쇄 할 내가 수 있다는

> apply(k,MARGIN=1,function(p) {p+1}) 
a b 
d 2 3 
e 4 5 

단 (K)에 함수를 적용 할 그 시점에서 기능이 적용된 행을 알아야합니다. 그것은 수도

은 다음과 같습니다

apply(k,MARGIN=1,function(p) {print(rowname(p)); p+1}) 

하지만 난 정말 R.에서 사람이 어떤 생각을 가지고 있습니까 그렇게하는 방법을하지 않는다?

+0

예상 답변을 명확히 할 수 있습니까? 'k'의 첫 번째 인스턴스에서 모든 숫자에 1을 더하면,'k'의 두 번째 인스턴스에서 응답을 얻지 못합니다. – ChrisW

+1

그냥 for 루프를 사용하십시오. – joran

+0

여기에는 정말 지저분한 제안이 많이 있습니다. 제안 된 솔루션이 귀하가 원하는 것을 수행하는지 알려주실 수 있습니까? –

답변

-3

나는 당신이 apply으로 할 수 없다는 것을 알고 있지만 데이터 프레임의 rownames을 반복 할 수 있습니다. 절름발이 예 :

lapply(rownames(mtcars), function(x) sprintf('The mpg of %s is %s.', x, mtcars[x, 1])) 
+0

당신은'apply'로 할 수 있습니다 - 그리고 일반적으로 정말 나쁜 아이디어를 루핑 할뿐만 아니라 위의 예제는 실제로 하나씩 출력합니다 (Sys.sleep() 딜레이를 넣으면 여러분은 그들 모두는 결국 하나의 버스트로 나옵니다.) ... –

+0

@TimP -'flush.console()'은 이것처럼 편리합니다. – Chase

+0

@TimP가 그의 대답에서 보여 주듯이, 이것은'apply()'에서 가능합니다. 이 대답은 오해의 소지가 있습니다. – Rhubarb

0

이렇게하면됩니다. cat() 함수는 함수를 평가하는 동안 결과를 인쇄 할 때 사용하려는 함수입니다. 반대로 paste()은 문자 벡터를 반환하지만 명령 창으로 보내지는 않습니다.

아래 해결책은 함수로 실행 된 횟수를 "기억"할 수 있도록 클로저로 생성 된 카운터를 사용합니다. 전역 할당 <<-의 사용에 유의하십시오. 여기서 무슨 일이 벌어지고 있는지 정말로 알고 싶다면이 위키를 통해 읽기를 권합니다. https://github.com/hadley/devtools/wiki/

참고 :이 방법을 사용하는 것이 더 쉬운 방법 일 수 있습니다. 내 솔루션은 적용 함수 내에서 일반적인 방법을 사용하여 현재 행의 rownumber 또는 rowname에 액세스 할 수있는 방법이 없다고 가정합니다. 앞서 언급했듯이 이것은 루프에서 아무런 문제가되지 않습니다.

k <- matrix(c(1,2,3,4),ncol=2) 
rownames(k) <- c("a","b") 
colnames(k) <- c("d","e") 


make.counter <- function(x){ 
    i <- 0 
    function(){ 
     i <<- i+1 
     i 
    } 
} 

counter1 <- make.counter() 

apply(k,MARGIN=1,function(p){ 
    current.row <- rownames(k)[counter1()] 
    cat(current.row,"\n") 
    return(p+1) 
}) 
4

당신은 행 인덱스를 추적하기 위해 적용 전화의 외부 변수를 사용하여 기능을 추가 인수로 행 이름을 전달할 수 있습니다 여기에

idx <- 1 
apply(k, 1, function(p, rn) {print(rn[idx]); idx <<- idx + 1; p + 1}, rownames(k)) 
+0

그것은 작동합니다! 하지만 여전히 전역 변수를 카운터로 사용해야합니다. 매우 우아하지 않습니다. –

+0

전역 변수를 사용할 수는 있지만 위의 솔루션에서는 이러한 작업이 필요하지 않습니다 (작업을 올바르게 이해했다고 가정 할 경우).) :) –

+0

이것은 for 루프에서 루핑 변수를 사용하는 것과 다르지 않습니다. 그것보다 우아하지 않습니다. – ALiX

12

하기에 깔끔한 솔루션 무엇 네가 묻고있는 것 같아. 아래 코드

결과 out1 - (이 예에서는 mat 2 칼럼 10 개 행을 갖고, 행 abc10을 통해 ABC1 명명 된 I는 명확성을 위해 입력 행렬 mat보다는 k라고했다.) 계산하려는 결과 (적용 명령의 결과)입니다. 결과 out2은 작업중인 rownames를 출력한다는 점을 제외하면 out1과 동일하게 나옵니다 (행당 0.3 초의 지연 시간을 가짐으로써 실제로이 작업을 수행 할 수 있음을 알 수 있습니다. 분명히 전속력으로 달린다!)

내가 생각해 낸 트릭은 mat의 왼쪽에 행 번호 (1에서 n까지)를 바인드하여 (하나의 추가 열이있는 행렬을 생성하기 위해) 이것을 참조하기 위해 사용한다. mat의 rownames에. x = y[-1] 행에 유의하십시오. 즉, 함수 내의 실제 계산 (여기에 1을 더함)은 행 번호의 첫 번째 열을 무시합니다. 이는 out1에 대해 수행 된 계산과 동일 함을 의미합니다.행에 대해 수행하려는 계산의 종류가 이와 같이 수행 될 수 있습니다. y이 존재하지 않았다고 가정하고 x을 사용하여 원하는 계산을 공식화하십시오. 희망이 도움이됩니다.

set.seed(1234) 
mat = as.matrix(data.frame(x = rpois(10,4), y = rpois(10,4))) 
rownames(mat) = paste("abc", 1:nrow(mat), sep="") 
out1 = apply(mat,1,function(x) {x+1}) 
out2 = apply(cbind(seq_len(nrow(mat)),mat),1, 
      function(y) { 
          x = y[-1] 
          cat("Doing row:",rownames(mat)[y[1]],"\n") 
          Sys.sleep(0.3) 
          x+1 
          } 
      ) 

identical(out1,out2) 
+1

허용 된 대답은 거짓이고 오해의 소지가있다. 이것은 받아 들여진 대답이어야합니다. – Rhubarb

0

간단히 행 이름의 새로운 열을 만든 다음 적용 호출에서 직접 참조 할 수 있습니까?

관련 문제