web-dev-qa-db-fra.com

Diviser chaque ligne de trame de données par un vecteur dans R

J'essaie de diviser chaque nombre dans un cadre de données avec 16 colonnes par un nombre spécifique pour chaque colonne. Les nombres sont stockés sous forme de trame de données avec 1-16 correspondant aux échantillons dans les plus grandes colonnes de trames de données 1-16. Il y a un nombre unique par colonne que je dois diviser par chaque nombre dans la feuille de calcul plus grande et imprimer le résultat dans une feuille de calcul finale.

Voici un exemple de ce que je commence avec. La feuille de calcul à diviser.

            X131.478.1 X131.478.2 X131.NSC.1 X131.NSC.2 X166.478.1 X166.478.2
1/2-SBSRNA4          4          2          2          6          7          6
A1BG                93         73         88         86         58         65
A1BG-AS1           123        103         96        128         46         57

Les nombres pour diviser la feuille de calcul par

X131.478.1 1.0660880
X131.478.2 0.9104053
X131.NSC.1 0.8642545
X131.NSC.2 0.9611866
X166.478.1 0.9711406
X166.478.2 1.0560121

Et les résultats attendus, pas forcément arrondis comme je l’ai fait ici.

    X131.478.1 X131.478.2 X131.NSC.1 X131.NSC.2 X166.478.1 X166.478.2
1/2-SBSRNA4          3.75          2.19          2.31          6.24          7.20         5.68
A1BG                87.23         80.17         101.82         89.47         59.72         61.55
A1BG-AS1           115.37        113.13         111.07        133.16         47.36         53.97

J'ai essayé simplement de diviser les trames de données mx2 = mx/sf, mx étant le grand jeu de données et sf étant le cadre de données contenant les nombres à diviser. Cela a semblé tout diviser par le premier nombre dans l'ensemble de données sf.

Les nombres pour la division ont été générés par estimationSizeFactors, qui fait partie du package DESeq si cela peut vous aider.

Toute aide est la bienvenue. Merci!

17
user1883101

sweep est utile pour ces types d'opérations. Par exemple, certaines données factices où nous divisons chaque élément dans les colonnes respectives de la matrice mat par la valeur correspondante dans le vecteur vec:

mat <- matrix(1:25, ncol = 5)
vec <- seq(2, by = 2, length = 5)

sweep(mat, 2, vec, `/`)

En cours d'utilisation nous avons:

> mat
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    2    7   12   17   22
[3,]    3    8   13   18   23
[4,]    4    9   14   19   24
[5,]    5   10   15   20   25
> vec
[1]  2  4  6  8 10
> sweep(mat, 2, vec, `/`)
     [,1] [,2]     [,3]  [,4] [,5]
[1,]  0.5 1.50 1.833333 2.000  2.1
[2,]  1.0 1.75 2.000000 2.125  2.2
[3,]  1.5 2.00 2.166667 2.250  2.3
[4,]  2.0 2.25 2.333333 2.375  2.4
[5,]  2.5 2.50 2.500000 2.500  2.5
> mat[,1] / vec[1]
[1] 0.5 1.0 1.5 2.0 2.5
34
Gavin Simpson

Juste pour la variété, vous pouvez aussi utiliser mapply

mx <- structure(list(X131.478.1 = c(4L, 93L, 123L), X131.478.2 = c(2L, 
73L, 103L), X131.NSC.1 = c(2L, 88L, 96L), X131.NSC.2 = c(6L, 
86L, 128L), X166.478.1 = c(7L, 58L, 46L), X166.478.2 = c(6L, 
65L, 57L)), .Names = c("X131.478.1", "X131.478.2", "X131.NSC.1", 
"X131.NSC.2", "X166.478.1", "X166.478.2"), class = "data.frame", row.names = c("1/2-SBSRNA4", 
"A1BG", "A1BG-AS1"))

sf <- structure(list(V1 = c(1.066088, 0.9104053, 0.8642545, 0.9611866, 
0.9711406, 1.0560121)), .Names = "V1", row.names = c("X131.478.1", 
"X131.478.2", "X131.NSC.1", "X131.NSC.2", "X166.478.1", "X166.478.2"
), class = "data.frame")


mapply(function(x, y) x * y, mx, t(sf))


    X131.478.1 X131.478.2 X131.NSC.1 X131.NSC.2 X166.478.1 X166.478.2
[1,]   4.264352   1.820811   1.728509    5.76712   6.797984   6.336073
[2,]  99.146184  66.459587  76.054396   82.66205  56.326155  68.640787
[3,] 131.128824  93.771746  82.968432  123.03188  44.672468  60.192690

Mais pour cela, je pense que la réponse de Josh est meilleure ... et celle de Gavin, encore meilleure!

2
Justin

Ce n’est rien mais multiplication de matrice par élément :

mat <- matrix(c(4,2,2,6,7,6, 93,73,88,86,58,65, 123,103,96,128,46,57), nrow=3, byrow=T)

vec = c(1.0660880,0.9104053,0.8642545,0.9611866,0.9711406,1.0560121)

mat %o% 1/vec

           [,1]      [,2]       [,3]       [,4]      [,5]      [,6]
[1,]   3.752035  2.080761   1.876018   6.242284  6.566062  6.242284
[2,] 102.152305 75.169342  96.660246  88.555663 63.707889 66.931606
[3,] 142.319190 97.536761 111.078392 121.210732 53.225063 53.976654

Pour ce faire, nous avons utilisé l’approche outer-product , car essayer directement mat %*% 1/vec donne une erreur sur non-conformable arguments car ils ont des formes différentes. Ou regardez les nombreux messages sur https://stackoverflow.com/search?q=%5Br%5D+multiply+matrix+by+vector

1
smci

Vous pouvez utiliser transform

mx2 <- transform(mx, 
    X131.478.1=X131.478.1/sf["X131.478.1",1],
    X131.478.2=X131.478.2/sf["X131.478.2",1],
    etc
)

Un peu à taper avec 16 colonnes, mais ça devrait marcher.

0
Karsten W.