2012-06-07 3 views
1

값의 벡터를 가지며이를 X라고하고 데이터 프레임을 dat.fram이라고 부릅니다. X의 각 요소와 일치하는 dat.fram [, 3]의 모든 색인을 찾기 위해 "grep"또는 "which"와 같은 것을 실행하고 싶습니다.벡터 버전/벡터화 a가 R과 동등한 루프를위한 것

이것은 아래에있는 매우 비효율적 인 루프입니다. X에 많은 관찰이 있고 "match.ind"의 각 구성원은 0 개 이상의 일치를 가질 수 있습니다. 또한 dat.fram은 1 백만 가지가 넘는 관측치를 보유하고 있습니다. R에서 벡터 함수를 사용하여이 프로세스를보다 효율적으로 만들 수있는 방법이 있습니까?

궁극적으로, 목록을 전달해야 dat.fram에서 적절한 값을 검색 할 다른 함수를 전달할 것이기 때문에 목록이 필요합니다.

코드 :

match.ind=list() 

for(i in 1:150000){ 
    match.ind[[i]]=which(dat.fram[,3]==X[i]) 
} 
+0

이 가능 함수가 당신이 통과 할 필요가 목록을 벡터화해야 하는가? match.ind의 개별 항목을 개별적으로 검사해야하는 이유는 무엇입니까? 한 번에 data.fram의 모든 적절한 값을 필요로합니까? – John

+0

예, 루핑 정말 느리게 여기에 - 만약 내가 올바르게 질문을 이해했습니다, 내가 게시 한 코드는 당신이 필요로 할 일을해야합니다 : –

답변

1

UPDATE :이 ... 정말 매끄러운의 일을

좋아, 와우, 난 그냥 발견 멋진 방법입니다. 다른 컨텍스트에서 유용할지 궁금해지기 ...?!

### define v as a sample column of data - you should define v to be 
### the column in the data frame you mentioned (data.fram[,3]) 

v = sample(1:150000, 1500000, rep=TRUE) 

### now here's the trick: concatenate the indices for each possible value of v, 
### to form mybiglist - the rownames of mybiglist give you the possible values 
### of v, and the values in mybiglist give you the index points 

mybiglist = tapply(seq_along(v),v,c) 

### now you just want the parts of this that intersect with X... again I'll 
### generate a random X but use whatever X you need to 

X = sample(1:200000, 150000) 
mylist = mybiglist[which(names(mybiglist)%in%X)] 

그리고 그게 전부입니다! 수표로,의는 myList에의 처음 3 개 행을 살펴 보자 : 3 (이 절에서 발생에도 불구하고) X에 표시되지 않는

> mylist[1:3] 

$`1` 
[1] 401143 494448 703954 757808 1364904 1485811 

$`2` 
[1] 230769 332970 389601 582724 804046 997184 1080412 1169588 1310105 

$`4` 
[1] 149021 282361 289661 456147 774672 944760 969734 1043875 1226377 

은 3에서 차이가있다. 그리고 4에 나와있는 숫자 4가 나타납니다 V의 인덱스 포인트입니다

> which(X==3) 
integer(0) 

> which(v==3) 
[1] 102194 424873 468660 593570 713547 769309 786156 828021 870796 
883932 1036943 1246745 1381907 1437148 

> which(v==4) 
[1] 149021 282361 289661 456147 774672 944760 969734 1043875 1226377 

을 마지막으로는, 그것은 X에 표시되지만 값이없는 절에서 목록의 항목이없는 것을 주목할 필요가 있지만, 이것은 아마 당신이 어쨌든 그들이 NULL이기 때문에 원하는 것입니다!

추가 참고 : 당신은 ...하지 V의 X의 각 구성원에 대한 NA 항목을 만들려면 아래 코드를 사용할 수 있습니다

blanks = sort(setdiff(X,names(mylist))) 
mylist_extras = rep(list(NA),length(blanks)) 
names(mylist_extras) = blanks 
mylist_all = c(mylist,mylist_extras) 
mylist_all = mylist_all[order(as.numeric(names(mylist_all)))] 
상당히 자기 설명

: mylist_extras 모두와 목록입니다 (이름은 이름에 포함되지 않은 X 값 (mylist)이며 목록의 실제 항목은 단순히 NA입니다). 마지막 두 줄은 먼저 mylist와 mylist_extras를 병합 한 다음 mylist_all의 이름이 숫자 순서로 정렬되도록 순서를 수행합니다. 이 이름은 벡터 X의 (고유 한) 값과 정확히 일치해야합니다.

건배! :)


위의 원본 포스트 ... 분명히 위! 여기

잘 빨리 크게 실행될 수 있습니다 tapply와 장난감 예제 ... 나는 X를 만들어 상대적으로 작은 그래서 당신은 무슨 일이 일어나고 있는지 볼 수 D :

X = 3:7 
n = 100 
d = data.frame(a = sample(1:10,n,rep=TRUE), b = sample(1:10,n,rep=TRUE), 
       c = sample(1:10,n,rep=TRUE), stringsAsFactors = FALSE) 

tapply(X,X,function(x) {which(d[,3]==x)}) 
+0

실제로 루프 메서드에 대한이 메서드에서 비슷한 런타임이있어 원래 포함되어 있습니다. 편집 : 원래 post._에 대한 응답으로 _Was –

+0

아주 멋지게 빨리 작동! 고맙습니다! 'X'에서 특정 값과 일치하는 것이 없다면 여전히 행을 가질 필요가 있기 때문에 다른 스크립트를 통해 null 값을 가진 행을 다시 삽입 할 수 있다고 확신합니다. –

+0

나는 추가 위치를 NA로 채우는 코드 ("추가 노트"에 있음)를 포함 시켰습니다. 공상을한다면 NA를 NULL로 변경하십시오 ... 가장 중요한 것은 여러분이 만든 최종리스트의 이름이 X에 포함 된 것을 놓치지 않는다는 것입니다! :) –