web-dev-qa-db-fra.com

soustraire un vecteur constant de chaque ligne d'une matrice en r

J'ai une matrice avec 5 colonnes et 4 lignes. J'ai également un vecteur avec 3 colonnes. Je veux soustraire les valeurs du vecteur des colonnes 3,4 et 5 respectivement à chaque ligne de la matrice.

b <- matrix(rep(1:20), nrow=4, ncol=5)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    9   13   17
[2,]    2    6   10   14   18
[3,]    3    7   11   15   19
[4,]    4    8   12   16   20

c <- c(5,6,7)

obtenir

     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    4    7   10
[2,]    2    6    5    8   11
[3,]    3    7    6    9   12
[4,]    4    8    7   10   13
21
user3651829

C'est exactement pour cela que sweep a été conçu:

b <- matrix(rep(1:20), nrow=4, ncol=5)
x <- c(5,6,7)

b[,3:5] <- sweep(b[,3:5],2,x)
b

#     [,1] [,2] [,3] [,4] [,5]
#[1,]    1    5    4    7   10
#[2,]    2    6    5    8   11
#[3,]    3    7    6    9   12
#[4,]    4    8    7   10   13

..ou même sans sous-ensemble ni réaffectation:

sweep(b,2,c(0,0,x))
49
thelatemail

Peut-être pas si élégant, mais

b <- matrix(rep(1:20), nrow=4, ncol=5)
x <- c(5,6,7)

b[,3:5] <- t(t(b[,3:5])-x)

devrait faire l'affaire. Nous sous-ensemble la matrice pour ne changer que la partie dont nous avons besoin, et nous utilisons t() (transposer) pour inverser la matrice afin qu'un simple recyclage de vecteur se charge de soustraire de la ligne correcte.

Si vous voulez éviter la transposition, vous pouvez faire quelque chose comme

b[,3:5] <- b[,3:5]-x[col(b[,3:5])]

ainsi que. Ici, nous sous-ensemble deux fois, et nous utilisons la seconde pour obtenir la colonne correcte pour chaque valeur dans x parce que ces deux matrices indexeront dans le même ordre.

Je pense que mon préféré de la question que @thelatemail a lié était

b[,3:5] <- sweep(b[,3:5], 2, x, `-`)
6
MrFlick

Une solution simple:

b <- matrix(rep(1:20), nrow=4, ncol=5)
c <- c(5,6,7)

for(i in 1:nrow(b)) {
  b[i,3:5] <- b[i,3:5] - c
}
2
Barranka

Une autre façon, avec appliquer:

b[,3:5] <- t(apply(b[,3:5], 1, function(x) x-c))
2
psadosky