2016-02-22 3 views
2

ORIGINAL ВОПРОС EDITEDУдаление строк из матрицы на основе столбца записей

Уважаемый R Пользователи,

У меня есть вопрос о удалении строк из матрицы. Все записи матрицы являются либо 0, либо 1. Строки сортируются в соответствии с суммой строк.

Вот пример матрицы

e1 <- c(0,0,0,1,0,0,0) 
e2 <- c(1,0,0,0,0,0,0) 
e3 <- c(0,1,0,0,0,0,0) 
e4 <- c(0,0,1,0,1,0,0) 
e5 <- c(1,1,0,0,0,0,0) 
e6 <- c(1,0,0,0,1,0,0) 
e7 <- c(0,0,0,0,0,1,1) 
e8 <- c(0,0,0,0,1,0,1) 
e9 <- c(0,0,1,0,1,1,0) 
e10 <- c(0,0,1,0,1,0,1) 
e11 <- c(0,0,0,0,1,1,1) 
e12 <- c(1,1,0,1,1,0,0) 
e13 <- c(0,0,1,1,0,1,1) 


(E <- rbind(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13)) 

который печатает

> (E <- rbind(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13)) 
[,1] [,2] [,3] [,4] [,5] [,6] [,7] 
e1  0 0 0 1 0 0 0 
e2  1 0 0 0 0 0 0 
e3  0 1 0 0 0 0 0 
e4  0 0 1 0 1 0 0 
e5  1 1 0 0 0 0 0 
e6  1 0 0 0 1 0 0 
e7  0 0 0 0 0 1 1 
e8  0 0 0 0 1 0 1 
e9  0 0 1 0 1 1 0 
e10 0 0 1 0 1 0 1 
e11 0 0 0 0 1 1 1 
e12 1 1 0 1 1 0 0 
e13 0 0 1 1 0 1 1 

Я хочу, чтобы удалить строки следующим образом. Если строка имеет одиночный 1, то все последующие строки ниже того, что с 1 в этой позиции столбца, должны быть удалены. Таким образом, мы наблюдаем строки e1 e2, а e3 может последовательно удалять строки e5, e6, e12 и e13. Оставляя нас рядами e1, e2, e3, e4, e7, e8, e9, e10 и e11.

for (v in 2:dim(E)[1]) 
{ 
print(v) 
print(E[v, 4]) 
if (E[v, 4] == 1) E <- E[-v,] 
} 

Удаление строк внутри цикла приводит к ошибке. Поэтому я подумал, что сначала найду строки (если есть), у вас есть строка 1 и идентифицировал их. Затем я пытаюсь удалить следующие строки с 1 в этой позиции, используя for-loop. Еще раз ошибка.

UnitRowsum <- E[which(rowSums(E) == 1),] 
UnitRowsum 

for (v in 1:dim(UnitRowsum)[1]) 
{ 
print(which(UnitRowsum[v, ] == 1)) 
} 

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

[,1] [,2] [,3] [,4] [,5] [,6] [,7] 
e1  0 0 0 1 0 0 0 
e2  1 0 0 0 0 0 0 
e3  0 1 0 0 0 0 0 
e4  0 0 1 0 1 0 0 
e7  0 0 0 0 0 1 1 
e8  0 0 0 0 1 0 1 
e9  0 0 1 0 1 1 0 
e10 0 0 1 0 1 0 1 
e11 0 0 0 0 1 1 1 

Сначала мы начать с рядами, которые имеют rowsum 1, и мы идем удалить все следующие строки с 1 в этом положении. Как только это будет сделано, мы увидим, есть ли строки с rowsum 2 слева. Да, мы идем вниз, ищем все строки, которые имеют 1s в обеих этих позициях и удаляют все такие строки. После этого мы переходим к строкам с rowsum 3 (если они есть) и продолжаем, как до тех пор, пока не получим матрицу, где ни одна строка не является доминирующей, чем другая.

Строка e4 доминирует над строками e9 и e10 и поэтому должна быть удалена. Строка e8 доминирует в строке e11 и поэтому ее также необходимо удалить. Это продолжается до тех пор, пока не удастся удалить больше строк. В конце концов я хочу получить матрицу

[,1] [,2] [,3] [,4] [,5] [,6] [,7] 
e1  0 0 0 1 0 0 0 
e2  1 0 0 0 0 0 0 
e3  0 1 0 0 0 0 0 
e4  0 0 1 0 1 0 0 
e7  0 0 0 0 0 1 1 
e8  0 0 0 0 1 0 1 

Не могли бы вы помочь мне в этом?

С уважением, Ash

ответ

0

Вот одно решение я придумал, что может работать:

E[!row.names(E) %in% unique(unlist(apply(E, 2, function(x) names(x[x == 1][2:length(x[x == 1])])))), ] 

Вы можете проверить каждую из этих частей, чтобы увидеть, что происходит.

Это дает список строк, где 1 протекают в каждом из столбцов матрицы:

apply(E, 2, function(x) names(x[x == 1])) 

Это дает список строк, где 1-х происходят после первого появления столбцов матрицы:

apply(E, 2, function(x) names(x[x == 1][2:length(x[x == 1])])) 

Это дает уникальные номера строк допущен к участию удаления:

unique(unlist(apply(E, 2, function(x) names(x[x == 1][2:length(x[x == 1])])))) 

Затем последний шаг - использовать фильтрацию/подмножество для удаления этих строк.

Возможно, вы упростите код, написав небольшую настраиваемую функцию для подачи до apply и оптимизируя бит, не дважды вызывая E[x == 1]. Но ... надеюсь, это поможет.

+0

Thanks Gopala за быстрый ответ. Очень ценю это. Я пробовал использовать его код. Однако я добавил еще одну строку в исходную матрицу и снова запустил код e11 <- c (0,0,0,0,0,1,1). Это строка, которую нельзя удалить, но она была удалена. – Ash

+0

Основываясь на вашем описании выше, строки e7 и e8 «превзошли» эту строку и должны быть удалены. Можете ли вы объяснить, почему эта строка должна быть сохранена? Возможно, вы также можете обновить свой вопрос. – Gopala

+0

Прошу прощения за неправильное объяснение моего вопроса. Сначала мы начинаем с строк, которые имеют rowsum 1, и мы удаляем все следующие строки с 1 в этой позиции. Как только это будет сделано, мы увидим, есть ли строки с rowsum 2 слева. Да, мы идем вниз, ищем все строки, которые имеют 1s в обеих этих позициях и удаляют все такие строки. После этого мы переходим к строкам с rowsum 3 (если они есть) и продолжаем, как до тех пор, пока не получим матрицу, где ни одна строка не является доминирующей, чем другая. Таким образом, строка, подобная e12 <- c (0,0,0,0,1,0,1), также останется нетронутой. Однако строка e13 <- c (0,0,0,0,1,1,1) будет удалена e12. – Ash

0
#This seems to do the trick (Thanks Cody) 

test = E 
for (i in (nrow(E)-1):1) 
{ 
    if (sum(E[i,]) == 0) 
    { 
    test = test[-c(i),] 
    next 
    } 
for (j in (nrow(test): (i))) 
{ 
    if ((j>nrow(test)) | (j==i)) 
    {break} 
    if (sum(xor(E[i,],test[j,])*1) == (sum(test[j,]) - sum(E[i,]))) 
    { 
     print(c(i,j)) 
     test = test[-c(j),] 
    } 
    } 
} 

E = test 

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