我有一个数据框mat
,它是基因矩阵的样本,其中包含值1, -1 or 0
,例如:
Gene1 Gene2 Gene5 Gene7
Sample1 1 0 -1 1
Sample2 0 -1 0 1
Sample3 -1 0 1 1
Sample4 1 1 0 0
另一个数据帧score
包含所有基因的相应分数,例如:
GeneName Score
Gene1 0.5
Gene2 0.3
Gene3 0.2
Gene4 0.6
Gene5 0.7
Gene6 0.1
Gene7 0.4
我要做的是在mat
中添加一个新列,其中包含一些基于等式的分数。等式是:
对于每一行,mat[1,1]
*得分为Gene1
+ mat[1,2]
*得分为Gene2
+ mat[1,3]
*得分为Gene5
+ { {1}} * mat[1,4]
的值。 Gene7
的每一行都相同。
例如,对于给定数据中的第一行,mat
的结果将为:
Sample1
对不起,如果这是一个愚蠢的问题。我是R的新手,仍在处理(1*0.5) + (0*0.3) + (-1*0.7) + (1*0.4) = 0.2
,%in%
和match
等内容。
数据
merge
答案 0 :(得分:1)
鉴于您的数据处于当前状态,您可以执行以下操作:
# get matching values
myVals <- as.numeric(score$Score[match(names(mat), score$GeneName, nomatch=FALSE)])
# Get the dot product for each row
apply(mat, 1, function(x) sum(as.numeric(x) * myVals))
Sample1 Sample2 Sample3 Sample4
0.2 0.1 0.6 0.8
第一行使用match
选择与mat列名对应的score
位置。然后使用[
提取相应的值。在第二行中,apply
使用提取的值计算每行mat的点积。
请注意,您的数字数据存储为字符,因此我使用as.numeric
来强制进行计算。
考虑到数据的结构,最好将它们存储为具有行名和列名的数字矩阵。
# turn mat into a matrix:
mat2 <- sapply(mat, as.numeric)
# dot product of each row: matrix multiplication
mat2 %*% myVals
[,1]
[1,] 0.2
[2,] 0.1
[3,] 0.6
[4,] 0.8
答案 1 :(得分:1)
以下是一种使用dplyr/tidyr
相当有效地完成此操作(无循环 - 应用函数)的方法:
library(dplyr)
library(tidyr)
mat$Sample <- row.names(mat)
row.names(mat) <- NULL
mat %>%
gather(GeneName, Value, -Sample) %>%
inner_join(., score) %>%
group_by(Sample) %>% summarise(score = sum(Value * Score))
输出是:
# A tibble: 4 × 2
Sample score
<chr> <dbl>
1 Sample1 0.2
2 Sample2 0.1
3 Sample3 0.6
4 Sample4 0.8