В R почему all.equal не найдет мне вектор в списке векторов? - PullRequest
0 голосов
/ 04 апреля 2020

Я пытаюсь написать некоторый код, чтобы найти указанный c вектор в огромном массиве векторов и вернуть индексы, где появляются копии этого вектора. В попытке отладки я пытаюсь изучить поведение all.equal (рекомендуется здесь , identical, по-видимому, исключено из-за несоответствия типов). Теперь я написал следующий код:

data<-replicate(100000,sample(4)) 
which( apply(data, 2, function(x) all.equal(c(1:4),data)) == TRUE)

Насколько я понимаю, первая строка написанного мной генерирует огромное количество перестановок целых чисел от 1 до 4, а вторая строка ищет их для любых случаев точной перестановки 1, 2, 3, 4. С точки зрения статистики, я очень уверен, что эта перестановка должна появиться где-то в этом списке, и в моем конкретном случае это девятая запись. Однако каждый раз, когда я запускал этот код или любое его изменение, мне говорили, что нужная перестановка никогда не появляется.

Что я делаю неправильно? Честно говоря, я начал подозревать, что совершил серьезную ошибку, когда мне пришлось искать, как найти вектор в списке векторов, и что для этого мне пришлось использовать две функции. Есть ли намного более простой способ?

Ответы [ 2 ]

2 голосов
/ 04 апреля 2020

На самом деле, вы были почти там, это просто маленькая опечатка. Правильный код:

which(apply(data, 2, function(x) all.equal(x, c(1, 2, 3, 4))) == TRUE)

, так как вам нужно предоставить данные для сравнения, а необходимые данные - это столбцы, а не весь набор данных. Как вы это сделали, он никогда не найдет совпадения, потому что весь массив никогда не будет соответствовать одному вектору.

1 голос
/ 04 апреля 2020

Попробуйте вместо этого:

which( apply(data, 2, function(x) all.equal(c(1:4),x)) == TRUE)

Разница в том, что в вашем коде вы сравниваете всю структуру, называемую data, с 1: 4, которая никогда не будет TRUE, так как размеры don ' т совпадают. Я заменил data на x внутри применяемой функции, поэтому теперь каждый отдельный столбец сравнивается с 1: 4.

В вашем коде также есть некоторые избыточности, c(1:4) - это такой же как 1:4. И all.equal, вероятно, излишне в этом случае, поскольку он делает больше, чем просто сравнение (он сравнивается с коэффициентом размытости и говорит вам, как все обстоит иначе). То, как вы используете его, вы конвертируете TRUE в символ. Было бы эффективнее не упрощать заранее. Вот быстрое сравнение (меньшие смоделированные данные):

> library(microbenchmark)
> 
> microbenchmark(
+   ae = {
+     data<-replicate(100,sample(4)) 
+     which( apply(data, 2, function(x) all.equal(c(1:4),x)) == TRUE)
+   },
+   e = {
+     data <- replicate(100, sample(4), simplify=FALSE)
+     which(sapply(data, function(x)all(x==(1:4))))
+   }
+ )
Unit: microseconds
 expr      min        lq      mean    median       uq       max neval cld
   ae 4063.205 4303.3370 4940.2126 4501.5080 4951.623 10953.339   100   b
    e  455.934  493.3115  578.4828  523.4605  562.601  2013.444   100  a 

Упрощенный код выполняется примерно в одну девятую (в среднем) времени.

...