2013-12-19 4 views
2

Рассмотрим следующую матрицу:Найти индекс конкретного столбца в R

mat = rbind(c(".","2","3","4","5","6"), 
      c(".","2","3","7","8","1"), 
      c(".","2","3","7","9","2")) 

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

В действительности матрица имеет очень большие размеры.

Есть ли простой способ получить индекс первых столбцов, для которых все элементы различны?

Спасибо!

ответ

2

Я хотел бы сделать что-то вроде:

which(apply(mat, 2, function(x) all(!duplicated(x))))[1] 
[1] 5 
+0

Отлично, спасибо! Но по какой-то причине он отлично работает с приведенным выше примером, но не так хорош в моей реальной матрице. – Mayou

+2

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

+0

Ну, матрица, которую я разместил, буквально является подмножеством моей большой матрицы. – Mayou

4

Вот альтернатива

> which(apply(mat, 2, function(x) all(!duplicated(x)))==TRUE)[1] 
[1] 5 
+0

+1, хотя '== TRUE, не требуется. –

+0

@PaulHiemstra ты прав. Я не буду редактировать, так как вы уже отправили его в качестве ответа;) –

2

инструменты вы ищете являются применить() и уникальный(). Мои проверки решение, которое матрица правильной длины:

apply(mat, 2, function(x) length(unique(x))==length(x)) 

Если вы хотели бы использовать это, чтобы получить только первый полный столбец,

answers<-mat[,apply(mat, 2, function(x) length(unique(x))==length(x))] 
answers[,1] 
0

Все другие решения лучше, чем у меня, но я думал, что все равно отправлю свой уродливый ответ.

min(which(lapply(sapply(apply(mat,2,rle),'[[',1),function(x)all(x==1))==T)) 
5

Вместо all(!duplicated(x)) вы можете также использовать anyDuplicated, например:

which(apply(mat, 2, anyDuplicated) == 0)[1] 
[1] 5 

Согласно ?anyDuplicated должно быть более эффективным:

'(.) AnyDuplicated' является «обобщенной "Более эффективный ярлык для 'any (дублированный (.))'

+0

короче, но не эквивалентно, если матрица не имеет такого столбца со всеми уникальными значениями. – flodel

3

Вы можете избежать превращения всех столбцов в логические, а затем сначала выбрать TRUE. Вы можете использовать простую for петлю и break завернутое в функции, как это:

findfirst <- function(mat) 
{ 
for(i in seq_len(ncol(mat))) { 
    if(!anyDuplicated(mat[,i])) break 
} 
return(i) 
} 
findfirst(mat) 
#[1] 5 
+0

Я бы на самом деле догадался, что это будет довольно хороший подход, а не проверка всех столбцов ... – A5C1D2H2I1M1N2O1R2T1

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