2013-05-10 3 views
1

Я хочу сравнить огромный вектор с выбранным элементом из матрицы в R.Сравните вектор с выбранным элементом из матрицы

А является матрицей и B является вектором. Я хочу сравнить каждый элемент B с выбранным элементом из A. C и D - критерии выбора. Они представляют собой векторы одинаковой длины, такие как B. C указывает номер строки A, а D указывает номер столбца. А имеет размерность 10 * 100, и В, С, D являются все векторы длины 72000. Код с цикл:

for (j in 1:length(B)){ 
    E[j] <- B[j] >= A[ C[j], D[j] ] 
} 

Это слишком медленно. I векторизовать это путем определения вектора, включающего элементы из A сначала:

A1 <- array(0, length(B)) 
A2 <- A[,D] 
for (j in 1:length(B)){ 
    A1[j] <- A2[ C[j], j ] 
} 
E <- B >= A1 

Это все еще слишком медленно. Есть ли лучший способ этого?

+0

Могу ли я спросить, нашли ли вы один из трех ответов ниже справки? – MatthewS

+0

Я думаю, что все они полезны. В этом случае третий с cbind быстрее. Однако, если A является 3 или более высоким размерным массивом, то второй более подходит. Я могу использовать A [C, D ,,] для его индексации. Однако неправильно использовать A [cbind (C, D) ,,]. – lionup

+0

Чтобы уточнить @lionup, если вы подмножите массив по одной матрице (например, 'A [cbind (C, D)]', вы получите вектор с одним значением для каждой строки в A. Если вы подмножество с использованием нескольких векторов (например, 'A [C, D]'), вы получите массив 'length (C)' x 'length (D)'. Оба полезны, когда это необходимо, но важно понимать, что они не совпадают! – MatthewS

ответ

1

Абсолютно быстрый способ, который я могу придумать, - это обработать А как вектор и извлечь нужные элементы. Матрица действительно просто вектор с атрибутами измерения. Арифметические операции выполняются очень быстро, а оператор подмножества [ векторизован.

Чтобы получить нужные элементы все, что вам нужно сделать, это умножить нужный вам номер столбца (D) от общего количества строк, а затем вычесть нужный номер строки (C) минус общее количество строк, например, A[ D * nrow(A) - (nrow(A) - C) ] как в этом пример:

set.seed(1234) 
A <- matrix(sample(5,16,repl=TRUE) , 4) 
# [,1] [,2] [,3] [,4] 
#[1,] 2 1 1 5 
#[2,] 1 3 5 5 
#[3,] 2 1 1 2 
#[4,] 1 4 2 1 

## Rows 
C <- sample(nrow(A) , 3 , repl = TRUE) 
#[1] 1 2 3 

## Columns 
D <- sample(ncol(A) , 3 , repl = TRUE) 
#[1] 1 3 2 

## Treat A as a vector 
## Elements are given by: 
rs <- nrow(A) 
A[ D * rs - (rs - C) ] 
#[1] 2 5 1 
+0

Из вашего ответа я узнал новый способ подстрочной матрицы. Благодарю. – lionup

+0

Я нахожу, что ваш метод действительно полезен при работе с более высоким размерным массивом. – lionup

+0

@ lionup Я рад, что вы сочли это полезным! Долгое использование R –

0

Я не уверен, что я полностью понимаю ваш вопрос, но я думаю, что вы хотите что-то вроде следующего:

# setup some mock data 
a <- matrix(rnorm(1000,0,1),nrow=10, ncol=100) 
b <- rnorm(100,0,1) 
c <- rep(1:10,10) 
d <- 1:100 

# define function 
compare <- function(v,row,column) 
    return(v >= a[row,column]) # you might want this to output to something else 

# apply the comparison function to the b, c, and d vectors 
mapply(FUN=compare, b, c, d) 
+0

Я сравнил ваш метод с метод ниже.Такой метод занимает 0,64 секунды, а один ниже занимает 0,52 секунды.Однако, я думаю, что ваш метод можно использовать более широко в случае, если «a» не является матрицей, а массивом с высоким размером. Затем я могу использовать [ строка, столбец ,,,], чтобы подписать его. Спасибо. – lionup

2

Вы можете легко выбрать каждый элемент, соответствующий каждой записи B, основываясь на критерии отбора в и С. Зерноуборочный в и с в матрицу из двух столбцов, а затем подмножество а с этой матрицей:

A.subset <- A[cbind(B, C)] 

Теперь у вас есть вектор (A.subset) той же длины, что и B, и может выполнять любое (векторное) сравнение, которое вам нравится в исполнении.

+0

Это действительно быстро. Спасибо. – lionup

+0

Я никогда не видел это использование 'cbind' раньше. Ницца! – Thomas

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