Векторизация вложенная для цикла, R - PullRequest
2 голосов
/ 30 сентября 2019

На самом деле, я хочу создать вектор «сравнить» с другим вектором «данные». Я хочу сравнить каждый элемент в «данных» с самим собой и со всем элементом, который следует в векторе. Если есть связь, я добавляю 1, чтобы «сравнить», если нет, я добавляю 0. Например:

data=c(3,6,7,3)
# I compare 3 to 3, 6, 7 and 3
# Then I compare 6 to 6, 7, and 3
# Then 7 to 7 an 3
# Then 3 to 3 so I get
compare=c(1,0,0,1,1,0,0,1,0,1)

Вот что я сделал:

for(i in 1:length(data))
{
  for(j in 0:(length(data)-i))
  {
     if (data[i]==data[i+j])
     {
        compare=append(compare,1)
     }
     else
     {
        compare=append(compare,0)
     }
  }
}

Есть ли способвекторизовать этот вид сравнения между элементами векторов?

Ответы [ 3 ]

3 голосов
/ 30 сентября 2019

Мы можем использовать dist:

data=c(3,6,7,3)
res <- as.matrix(dist(data))
res <- res < .Machine$double.eps #find elements with distance of 0
diag(res) <- 1
res[lower.tri(res, TRUE)]
#[1] 1 0 0 1 1 0 0 1 0 1
2 голосов
/ 30 сентября 2019

Мы можем использовать outer для сравнения data с самим собой, а затем извлекать данные нижнего треугольника, чтобы мы получали выходные данные только тех данных, которые следуют за текущим значением.

mat <- +(outer(data, data, `==`))
mat[lower.tri(mat, diag = TRUE)]
#[1] 1 0 0 1 1 0 0 1 0 1
1 голос
/ 30 сентября 2019

Вы можете использовать sapply для индекса:

as.numeric(unlist(sapply(1:length(data), function(k) data[k] == data[k:length(data)])))
[1] 1 0 0 1 1 0 0 1 0 1

Текущее значение индекса k сравнивается со всеми значениями, равными или после k. unlist позволяет объединить результат каждой итерации k. Наконец as.numeric преобразует логические значения в целые.

...