2013-09-10 2 views
3

Я хочу, чтобы проверить, содержит ли вектор y другой вектор xчек, если вектор содержит другой вектор

y <- c(0,0,0,NA,NA,0) 
x <- c(0,0,0,0) 

В этом случае он должен дать мне FALSE, потому что нет последовательности из четырех NULL в y. Но если взглянуть на вектор y2, результат должен быть TRUE.

y2 <- c(0,0,NA,0,0,0,0) 

EDIT:

Я пытался использовать %in%, но, кажется, работает только для элементов векторов, а не для целых векторов. Решение не должно быть применимо к более общим проблемам. Было бы неплохо, если бы он работал в этом конкретном случае.

+2

-1 Что вы пробовали? См. [Как задать хороший вопрос?] (Http://stackoverflow.com/help/how-to-ask) и [Контрольный список вопросов по StackOverflow] (http://meta.stackexchange.com/q/156810) , –

+0

Я не понимаю, почему это имеет значение. Все, что я пробовал, не дало ожидаемого результата. Поэтому я спрашиваю здесь. Что не хватает в моем вопросе? – beginneR

+5

Вы посмотрели на одну из ссылок в моем предыдущем комментарии? Они обсуждают, почему это имеет значение. Кроме того, если вы не показываете, что вы пробовали, похоже, вы просто просите других сделать вашу работу за вас. –

ответ

6

Вы можете использовать комбинации grepl и paste. Здесь вам нужно свернуть каждый вектор на один символ, используя аргумент collapse в paste.

> grepl(paste(x,collapse=";"),paste(y2,collapse=";")) 
[1] TRUE 
> grepl(paste(x,collapse=";"),paste(y,collapse=";")) 
[1] FALSE 

> grepl(paste(c(123),collapse=";"),paste(c(12,3),collapse=";")) 
[1] FALSE 
+0

Теперь он отлично работает для числовых векторов. Однако могут быть некоторые редкие конфликты с персонажами. –

+0

Именно поэтому я спросил, было ли это больше, чем просто 0 и НС, и вы избили меня до ответа! :) – Spacedman

+0

@dayne Приобретено. Когда я пытался решить эту проблему, у меня получилось такое же решение. Вам не нужно использовать ''; '', 'collapse = ''' достаточно. –

4

Используйте это:

any(apply(embed(y,length(y)-length(x)+1),2,identical,x)) 
+0

Я должен сейчас поработать, но я очень рад это посмотреть позже. Никогда бы не подумал приблизиться к нему так. Любите этот сайт! – dayne

4

Только для тех, кто мог бы задаться вопросом, тест времени ответов.

findit1<-function(x,y) any(apply(embed(y,length(y)-length(x)+1),2,identical,x)) 
findit2<-function(x,y) grepl(paste(x,collapse=";"),paste(y,collapse=";")) 

x<-c(0,1,1,0,0,0,1,0,1) 
y<-sample(c(0,1),1e5,replace=TRUE) 

Rgames> microbenchmark(findit1(x,y),findit2(x,y)) 
Unit: milliseconds 
      expr  min  lq median  uq  max neval 
findit1(x, y) 403.79291 449.9028 457.8320 466.4996 603.6573 100 
findit2(x, y) 99.09317 100.7774 101.4513 102.1728 119.8970 100 

EDIT: используя rle ответ EDDI, в

Rgames> findit3<-function(x,y) sum(length(x) <= rle(y)$lengths[rle(y)$values %in% 0]) 
Rgames> x<-c(0,0,0,0,0) 
Rgames> microbenchmark(findit1(x,y),findit2(x,y),findit3(x,y)) 
Unit: milliseconds 
      expr  min  lq median  uq  max neval 
findit1(x, y) 340.63570 383.39450 414.6791 456.38786 532.98017 100 
findit2(x, y) 99.72606 101.11308 101.9399 103.20869 117.91149 100 
findit3(x, y) 23.39226 24.39826 31.8478 35.10592 53.15408 100 

Но в общем случае любой последовательности в x я сомневаюсь, что есть способ массажа rle или seqle, чтобы сделать это. Мне нужно немного поиграть с вещами. :-)

0

Еще один вариант:

length(x) == max(nchar(strsplit(paste(y,collapse=''),"NA")[[1]])) 
length(x) == max(nchar(strsplit(paste(y2,collapse=''),"NA")[[1]])) 

Я также думаю, что должно быть разумным способом, например, используйте как-то cumsum (и сбросьте его до 0 при каждом появлении NA, а затем получите максимум и сравните его с длиной x). После некоторого поиска в Интернете у меня есть:

length(x) == max(sapply(split(y, replace(cumsum(is.na(y)), is.na(y), -1))[-1],length)) 
length(x) == max(sapply(split(y2, replace(cumsum(is.na(y2)), is.na(y2), -1))[-1],length)) 

Или, может быть, чтобы начать с which(is.na(x)), а затем каким-то образом вычислить максимальную разницу между элементами в результате.

3

Для этого конкретного случая 0-х только в x, просто использовать rle:

sum(length(x) <= rle(y2)$lengths[rle(y2)$values %in% 0]) > 0 
#[1] TRUE 
sum(length(x) <= rle(y)$lengths[rle(y)$values %in% 0]) > 0 
#[1] FALSE 
+1

+1 Есть базовая функция для всех в R, но для их запоминания требуются годы. :) –

1

ОП не просил об этом, но вот способ найти, где происходят случаи x. Я использовал «9» в качестве моего тега-символа в предположении, что «9» никогда не появляется в y. Очевидно, можно было выбрать другого персонажа.

> bar<-gsub(paste(x,collapse=""),'9',paste(y,collapse="")) 
> rab<-as.numeric(unlist(strsplit(bar,''))) 
> rle(rab==9) 
Run Length Encoding 
    lengths: int [1:3123] 49 1 49 1 20 1 6 1 78 1 ... 
    values : logi [1:3123] FALSE TRUE FALSE TRUE FALSE TRUE ... 
0

Аналогично (хорошее использование embed(), BTW) Фердинандом, это возвращает вектор всех матчей (пусто, если нет):

which(sapply(1:(length(y)-length(x)+1), function(z) identical(x, y[z:(z+length(x)-1)])))

Смежные вопросы