2017-03-24 3 views
3

내 질문이 중복되었지만 stackoverflow에서 검색 한 결과 가능한 해결책이 없는지 확실하지 않습니다.정렬 된 문자의 벡터를 기반으로 데이터 프레임의 행을 필터링하십시오.

I가 I 다음 dataframe 결과 숯 열에서 (이 순서로) 단어 빙고 형성 행만 선택하고자

num char 
1  A 
2  K 
3  I 
4  B 
5  I 
6  N 
7  G 
8  O 
9  Z 
10 Q 

다음 데이터 프레임 :

num char 
4  B 
5  I 
6  N 
7  G 
8  O 

도움을 주시면 감사하겠습니다.

+0

이들은 항상 단일 문자입니까? 문자열에 붙여 넣기가 쉽고 정규 표현식이나 간단한 문자열 일치를 사용하여 올바른 색인을 찾는 것이 더 쉬운 것처럼 보입니다. – MrFlick

+0

안녕하세요 MrFlick, 예, 항상 단일 문자입니다. 그러나 제안 된 솔루션을 구현하는 방법을 이해하지 못합니다 ... –

+0

당신은,이 비슷한 찾을 수 있습니다 [게시물] (http://stackoverflow.com/questions/33027611/how-to-index-a-vector- sequence-within-a-vector-sequence) 도움이됩니다. –

답변

0
d = data.frame(num=1:15, char=c('A', 'K', 'I', 'B', 'I', 'N', 'G', 'O', 'Z', 'Q', 'B', 'I', 'N', 'G', 'O')) 
w = "BINGO" 
N = nchar(w) 
char_str = paste(d$char, sep='', collapse='') 

idx = as.integer(gregexpr(w, char_str)[[1]]) 
idx = as.integer(sapply(idx, function(i)seq(i, length=N))) 
d[idx, ] 

    num char 
4 4 B 
5 5 I 
6 6 N 
7 7 G 
8 8 O 
11 11 B 
12 12 I 
13 13 N 
14 14 G 
15 15 O 
+0

본인의 예를 이해할 수 없습니다. 'gregexpr()'함수로 어떻게 행을 선택할 수 있습니까? 당신이 작은 설명을하면 좋을 것입니다. –

+0

좋아 보인다. 하지만 순서가 맞지 않으면 작동하지 않습니다. 이'd = data.frame (num = 1 : 15, char = c (A, K, I, B, N, I, G, O) ','Z ','Q ','X ','I ','N ','G ','O '))' –

+0

OP는 순서가 일치해야합니다. – Fernando

3

하나의 옵션은 사용하는 것입니다 zoo::rollapply :

library(zoo) 
bingo = c("B", "I", "N", "G", "O") # the pattern you want to check 

# use rollapply to check if the pattern exists in any window 
index = which(rollapply(df$char, length(bingo), function(x) all(x == bingo))) 

# extract the window from the table 
df[mapply(`:`, index, index + length(bingo) - 1),] 

# num char 
#4 4 B 
#5 5 I 
#6 6 N 
#7 7 G 
#8 8 O 
+0

감사합니다. 그게 내가 필요한 것! –

0

나는 아무도 루프처럼 생각하지만,이 자료의 가능성이다 : 나는 너무 빨리 처음 있지만 기반 갔다

char <- c("A", "K", "I", "B", "I", "N", "G", "O", "Z", "Q") 
num <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 
df <- data.frame(num, char) 

word <- "BINGO" 
index <- NULL 
for(z in 1:nrow(df)){ 
    if(substr(word, 1,1) == as.character(df[z,2])){ 
    index <- c(index, z) 
    word <- substr(word, 2, nchar(word))  
    } 
} 

df[index,] 
0

당신이 준 예제에서, 나는 이것이 작동 할 수 있다고 생각한다 :

filter(df[which(df$char == "B"):dim(df)[1],], char %in% c("B","I","N","G","O")) 
+0

해결책과 함께 다음과 같은 오류 메시지가 나타납니다 : '필터 오류 (% df [char (1)], dim (df) 'filter'가 시계열보다 길다 ' –

1

다음은 재귀 함수를 사용하는 해결책입니다. BINGO의 문자는 연속적 일 필요는 없지만 순서대로 정렬해야합니다.

df <- data.frame(num=1:10,char=c("A","K","I","B","I","N","G","O","Z","Q"),stringsAsFactors = FALSE) 

word<-"BINGO" 

chars<-strsplit(word,"")[[1]] 

findword <- function(chars,df,a=integer(0),m=0){ #a holds the result so far on recursion, m is the position to start searching 
    z <- m+match(chars[1],df$char[(m+1):nrow(df)]) #next match of next letter 
    if(!is.na(z)){  
    if(length(chars)==1){ 
     a <- c(z,a) 
    } else { 
     a <- c(z,Recall(chars[-1],df,a,max(m,z))) #Recall is function referring to itself recursively 
    } 
    return(a) #returns row index numbers of df 
    } else { 
    return(NA) 
    } 
} 

result <- df[findword(chars,df),] 
+0

내 솔루션보다 50 % 더 빠르고 우아함 +1 –

+0

감사합니다. 기능에'is.na (z) '가 있는지 확인하는 것이 좋습니다. 단어가 발견되지 않으면 지독한 충돌. 위의 편집. –

관련 문제