Индекс строк, в котором один столбец имеет ненулевую запись

João Carvalho спросил: 28 апреля 2018 в 08:33 в: r

Я думаю, что это может быть повторный вопрос, но я не могу найти ответ, так что вот оно. Если у меня есть матрица X:

 > X
       [,1] [,2] [,3] [,4] [,5]
  [1,]   1    4   55    1    8
  [2,]  48    2    0    1    2
  [3,]  67   23   53   55   78
  [4,]   0   78    0    0    0
  [5,]  85   91   23   65   83

Каков самый простой способ получить индекс строки, где одна запись отлична от нуля, а все остальные равны нулю? Я пробовал:

test <- which(X[,2] != 0 & X[,-2] == 0)

И в идеале я хотел бы, чтобы результат был: 4. Но это не то, что происходит ... Я получаю, что which() дает мне индекс (строка и столбец), так что, вероятно, это не способ решить эту проблему ... Любые идеи?

Спасибо заранее!

2 ответа

Есть решение
Moody_Mudskipper ответил: 28 апреля 2018 в 09:31
X <- as.matrix(read.table(text="
 1    4   55    1    8
48    2    0    1    2
67   23   53   55   78
 0   78    0    0    0
85   91   23   65   83"))which(rowSums(X!=0)==1)
# [1] 4

Вот два способа исправить ваш подход, обратите внимание, что они сосредоточены на наблюдении за столбцом 2, в то время как мое решение не выполняет:

which(X[,2] != 0 & rowSums(X[,-2] != 0)==0) # [1] 4
which(X[,2] & !apply(X[,-2],1,any,0))       # [1] 4

потому что X[,-2] == 0 - это матрица логических элементов, а не вектор, который вы бы хотели.

Если вы хотите сделать это для всех столбцов отдельно, вы можете использовать lapply:

lapply(seq(ncol(X)),function(i) which(X[,i] != 0 & rowSums(X[,-i] != 0)==0))
João Carvalho ответил: 28 апреля 2018 в 08:50
Это работает для этого конкретного примера. Однако моя реальная проблема сложнее, потому что у меня есть большая матрица (2 ГБ) со многими строками и 19 столбцами, и я хочу найти, сколько строк имеет ненулевую запись для первого столбца и нулевые записи для всех остальных столбцов. И тогда сделайте то же самое для всех остальных 18 столбцов. Но спасибо за вход!
Moody_Mudskipper ответил: 28 апреля 2018 в 08:52
Проверьте мое обновление по исправлению вашего подхода и возьмите первый (с rowSums), поскольку он будет быстрее. заменяя 2 на 1
Moody_Mudskipper ответил: 28 апреля 2018 в 08:54
попробуйте следующее: lapply(seq(ncol(X)),function(i) which(X[,i] != 0 & rowSums(X[,-i] != 0)==0)). Если это не даст результат, который вы хотите, пожалуйста, обновите свой вопрос, это не сложная проблема, но я не уверен, какой формат вывода вы хотите.
João Carvalho ответил: 28 апреля 2018 в 08:58
Последнее решение с использованием lapply работает отлично! большое спасибо
Terru_theTerror ответил: 28 апреля 2018 в 08:59

Попробуйте этот простой пример кода:

    m<-as.matrix(cbind(a=c(1,1,1,0,0,1),b=c(1,1,1,1,0,0),c=c(1,1,1,0,0,0)))
> m
     a b c
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
[4,] 0 1 0
[5,] 0 0 0
[6,] 1 0 0
> 
> #Row detection
> which(rowSums(m!=0)==1)
[1] 4 6
> 
> #Column with elemnte !=0
> apply(m[which(rowSums(m!=0)==1),],1,which.max)
[1] 2 1
João Carvalho ответил: 28 апреля 2018 в 08:50
Как уже упоминалось, это работает для этого конкретного примера. Однако моя реальная проблема сложнее, потому что у меня есть большая матрица (2 ГБ) со многими строками и 19 столбцами, и я хочу найти, сколько строк имеет ненулевую запись для первого столбца и нулевые записи для всех остальных столбцов. И тогда сделайте то же самое для всех остальных 18 столбцов. Но спасибо за вход!
Terru_theTerror ответил: 28 апреля 2018 в 08:59
Код обновлен в соответствии с этим пунктом.