Как суммировать столбцы в матрицах по определенному правилу? - PullRequest
0 голосов
/ 30 мая 2018

сейчас у меня много матриц с разным количеством строк.И я хочу суммировать строки с нечетными числами и элементы с четными номерами соответственно, как показано ниже:

o <- matrix(rep(c(1,2,3,4,5,6),6),ncol = 6)
o2 <- matrix(rep(c(1,2,3,4,5,6),12),ncol = 6)   
#I want to sum the odd-number rows and even number rows element respectively
i=1
kg <- NULL
while(i <= 2){
op<-unlist(Map(sum,o[i,],o[i+2,],o[i+4,]))
kg <- c(kg,op)
i=i+1
}

i=1
kg2 <- NULL
while(i <= 2){
op2<-unlist(Map(sum,o2[i,],o2[i+2,],o2[i+4,],o2[i+6],o2[i+8],o2[i+10]))
kg2 <- c(kg2,op2)
i=i+1
}
kg
kg2 #the result should be a vector sequence like kg and kg2
> kg2
[1] 18 18 18 18 18 18 24 24 24 24 24 24

Это то, что я могу знать.Но мои данные имеют много разной длины столбцов.Это какой-то метод, которым я могу сделать это быстро?

И как я могу создать строку типа "o2 [i,], o2 [i + 2,], o2 [i + 4,], o2 [i + 6], o2 [i + 8], o2 [i + 10]) "автоматически по введенному номеру?Спасибо за вашу помощь:)

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

В цикле ОП, если мы хотим изменить Map, чтобы сделать его более автоматическим

unlist(do.call(Map, c(f = sum, as.data.frame(t(o2[seq(i, i+10, by = 2),])))))

Используя полный код

o <- matrix(rep(c(1,2,3,4,5,6),6),ncol = 6)
o2 <- matrix(rep(c(1,2,3,4,5,6),12),ncol = 6)   
#I want to sum the odd-number rows and even number rows
i=1
kg <- NULL
while(i <= 2){
#op<-unlist(Map(sum,o[i,],o[i+2,],o[i+4,]))
op <- unlist(do.call(Map, c(f = sum, 
        as.data.frame(t(o[seq(i, i+4, by = 2),]))))) # change here

kg <- c(kg,op)
i=i+1
}

i=1
kg2 <- NULL
while(i <= 2){
#op2<-unlist(Map(sum,o2[i,],o2[i+2,],o2[i+4,],o2[i+6],o2[i+8],o2[i+10]))
op2 <- unlist(do.call(Map, c(f = sum, 
               s.data.frame(t(o2[seq(i, i+10, by = 2),]))))) # change here

kg2 <- c(kg2,op2)
i=i+1
}
kg
#[1]  9  9  9  9  9  9 12 12 12 12 12 12

kg2
#[1] 18 18 18 18 18 18 24 24 24 24 24 24

В коде OP, если мы проанализируем отдельные аргументы Map только с двумя аргументами, то есть первая и третья строка 'o'

i <- 1
Map(function(x, y) c(x, y),  o[i,], o[i+2,])
#[[1]]
#[1] 1 3

#[[2]]
#[1] 1 3

#[[3]]
#[1] 1 3

#[[4]]
#[1] 1 3

#[[5]]
#[1] 1 3

#[[6]]
#[1] 1 3

Здесь каждый элемент list является столбцомобъединенные значения (c).Если нам нужно получить аналогичную структуру путем подстановки нечетных строк, мы транспонируем подмножество строк, преобразуем его в data.frame, чтобы каждый отдельный блок представлял собой столбец (который соответствует исходным подмножествам строк)

do.call(Map, c(f=c, as.data.frame(t(o[c(i, i+2),]))))
#[[1]]
#V1 V2 
# 1  3 

#[[2]]
#V1 V2 
# 1  3 

#[[3]]
#V1 V2 
# 1  3 

#[[4]]
#V1 V2 
# 1  3 

#[[5]]
#V1 V2 
# 1  3 

#[[6]]
#V1 V2 
# 1  3 

Сохранение его как matrix не решит его, так как он принимает всю матрицу как одну ячейку (matrix - это vector с атрибутом измерения)

do.call(Map, c(f=c, o[c(i, i+2),]))
#[[1]]
#[1] 1 3 1 3 1 3 1 3 1 3 1 3

, в то время какпрямое использование Map будет циклически проходить через каждый элемент matrix (vector) вместо каждого столбца

Map(c, o[c(i, i+2),]) # check the output

Другим вариантом будет split объект с помощью col и затем выполнениеsum

onew <- o[seq(i, i+4, by = 2),]
Map(sum, split(onew, col(onew)))

Вышеуказанный подход является зацикленным, но мы также можем использовать векторизованный подход (как в посте @Maurits Evers).Вместо seq здесь мы используем переработку логического вектора для подстановки строк, а затем делаем colSums

i1 <- c(TRUE, FALSE)
colSums(cbind(o[i1,], o[!i1,]))
#[1]  9  9  9  9  9  9 12 12 12 12 12 12

colSums(cbind(o2[i1,], o2[!i1,]))
#[1] 18 18 18 18 18 18 24 24 24 24 24 24
0 голосов
/ 30 мая 2018

Возможно, что-то вроде этого?

o <- matrix(rep(c(1,2,3,4,5,6),6),ncol = 6)
o2 <- matrix(rep(c(1,2,3,4,5,6),12),ncol = 6)

even <- function(x) 2 * seq(1, nrow(x) / 2);
odd <- function(x) 2 * seq(1, nrow(x) / 2) - 1;

colSums(o[even(o), ]);
#[1] 12 12 12 12 12 12

colSums(o[odd(o), ]);
#[1] 9 9 9 9 9 9

colSums(o2[even(o2), ]);
#[1] 24 24 24 24 24 24

colSums(o2[odd(o2), ]);
#[1] 18 18 18 18 18 18

Объяснение: even / odd вернуть четные / нечетные индексы строки a matrix / data.frame;затем мы можем использовать colSums для суммирования записей по столбцам.


Обновить

Для суммирования записей из строк 3, 6, 9, 12 (или любой другой последовательности) вам просто нужно определить соответствующийфункция, например

another_seq <- function(x) 3 * seq(1, nrow(x) / 3)
colSums(o2[another_seq(o2), ]);
#[1] 18 18 18 18 18 18
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...