Как я могу разделить матрицу на две части на основе сумм строк в R?

#r

#r

Вопрос:

Если у меня есть эта матрица, MatrixA:

         sample1 sample2 sample3
red 0   0   1
blue    47  39  44
green   18  109 6
orange  4   78  1000
  

Я хочу создать 2 отдельные матрицы на основе сумм строк. В MatrixB будут все строки, где сумма строк > = 100, а в MatrixC будут все строки, где сумма строк < 100.

Я попробовал несколько итераций с использованием сумм строк, однако я либо получаю одинаковые матрицы как для MatrixB, так и для MatrixC, либо я получаю MatrixC с ровно на 100 строк меньше, чем MatrixB. Мои фактические данные имеют > 100 тысяч строк.

 keep <- rowSums(MatrixA)>= 100
remove <- rowSums(MatrixA)< 100
MatrixB <- MatrixA[keep,]
MatrixC <- MatrixA[!!keep,]
  

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

 MatrixB

    sample1 sample2 sample3
blue    47  39  44
green   18  109 6
orange  4   78  1000

MatrixC

    sample1 sample2 sample3
red 0   0   1
  

Комментарии:

1. Может быть, просто опечатка !!keep = keep ? Должно быть !keep .

2. @stefan Спасибо, я на самом деле попробовал и то, и другое!! keep и !keep, ни то, ни другое не привело к желаемому результату.

Ответ №1:

Попробуйте это решение. Вы можете создать переменную индекса I на основе сумм строк и порогового значения, которое вы хотите. После этого вы можете использовать split() и сохранить результаты в списке. При этом вы получите желаемый результат:

 #Code
#Create rowsums
df$I <- ifelse(rowSums(df[,-1])>=100,'Keep','Remove')
#Now split
List <- split(df,df$I)
#Remove I var
List <- lapply(List,function(x) {x$I<-NULL;return(x)})
  

Вывод:

 List
$Keep
     var sample1 sample2 sample3
2   blue      47      39      44
3  green      18     109       6
4 orange       4      78    1000

$Remove
  var sample1 sample2 sample3
1 red       0       0       1
  

Некоторые используемые данные:

 #Data
df <- structure(list(var = c("red", "blue", "green", "orange"), sample1 = c(0L, 
47L, 18L, 4L), sample2 = c(0L, 39L, 109L, 78L), sample3 = c(1L, 
44L, 6L, 1000L), I = c("Remove", "Keep", "Keep", "Keep")), row.names = c(NA, 
-4L), class = "data.frame")
  

Если вы хотите перенести фреймы данных в среду, вы можете использовать следующий код:

 #Code
list2env(List,envir = .GlobalEnv)
  

Он установит все фреймы данных в вашей среде с именами Keep и Remove .

Теперь в случае, когда у вас есть матрица, вы должны использовать следующий код:

 #Create index
index <- which(rowSums(mat)>=100)
#Create matrices
m1 <- mat[index,]
m2 <- mat[-index,,drop=F]
m1
m2
  

Вывод:

 m1
       sample1 sample2 sample3
blue        47      39      44
green       18     109       6
orange       4      78    1000

m2
    sample1 sample2 sample3
red       0       0       1
  

Используемая матрица:

 #Matrix
mat <- structure(c(0L, 47L, 18L, 4L, 0L, 39L, 109L, 78L, 1L, 44L, 6L, 
1000L), .Dim = 4:3, .Dimnames = list(c("red", "blue", "green", 
"orange"), c("sample1", "sample2", "sample3")))
  

Комментарии:

1. Ваш пример с матрицей сработал отлично. Спасибо вам за такой понятный ответ!