【问题标题】:Improving my R Code to calculate Z score of dataframe改进我的 R 代码以计算数据帧的 Z 分数
【发布时间】:2016-04-14 22:26:36
【问题描述】:

我的任务是生成用于计算 Z 分数的 R 代码,然后将其输出到文件中。虽然脚本有效,但我对一些令我感到困惑的行有一些疑问。 输入.txt:

GeneID GeneID-2 GeneName TSS-ID Locus-ID Sample1 Sample2 Sample3 Sample4 Sample5 ID1 X1 Zranb2 TSS1 Loc1 22.49161667 14.7231 19.62885833 26.16171667 39.3109 ID2 X2 Lphn2 TSS2 Loc2 6.439735 5.920786667 8.883331667 7.696353333 10.46969333 ID3 X3 Rpf1 TSS3 Loc3 30.67975 20.93751667 27.30251667 31.55653333 58.57418333 ID4 X4 Ctbs TSS4 Loc4 1.916071667 1.943611667 2.696701667 3.130295 2.74012 ID5 X5 Spata1 TSS5 Loc5 0.715265667 0.3318745 0.4183155 0.961065833 1.10731 ID6 X6 Sap30bp TSS6 Loc6 21.65946667 23.84386667 28.39683333 25.32866667 26.96016667 ID7 X7 Recql5 TSS7 Loc7 7.541321667 4.674345 4.40599 3.24996 3.327395 ID8 X8 Itgb4 TSS8 Loc8 37.3442 51.58868333 51.58868333 44.84458333 42.44406667

我想为从样本 1 开始到列末尾的数据列生成 Z 分数。 这是我写的 R 代码:

df <- read.table("Input.txt", row.names=1, header=TRUE, sep="\t", na.strings="NA")
x<-df[,5:ncol(df)] #selects the columns after column 5, so just the data
p<-matrix(0, now(x), ncol(x)) #opens matrix. First issue: I used "0" as I saw other people on forums doing that, but i dont know its significance.It worked for me, so i kept it. Can anyone comment on this?
#Create a loop for row and columns
for (i in 1:nrow(x)) {
    for (j in 1:ncol(x)) {
    p[i,j] <- (x[i,j]-rowMeans(x[i,]))/sd(x[i,])
}
}

以上脚本成功生成矩阵。有没有办法优化它或者这是一个合理的方法?我的庞大数据集有点慢,但它完成了工作。

输出文件时,我的标题发生了变化。我的目标是将 df 的第一列输出为行名,然后将每个样本名称作为标题输出。为此,我使用了:

rownames(p) <-rownames(df)
colnames(p) <- colnames(df[,5:ncol(df)])
write.table(p, file = "Zscore.txt", append = FALSE, quote = FALSE, sep = "\t", row.names = TRUE, col.names = TRUE)

输出文件如下:

样品 1 样品 2 样品 3 样品 4 样品 5 ID1 -0.212153637 -1.048074183 -0.520196808 0.182762424 1.597662204 ID2 -0.780453984 -1.061276795 0.541869723 -0.100449696 1.400310753 ID3 -0.216506298 -0.890314297 -0.450087937 -0.1558648 1.712773332 ID4 -1.064932662 -1.013415279 0.395343854 1.206440228 0.476563859 ID5 0.02537058 -1.119050742 -0.861024653 0.759083238 1.195621576 ID6 -1.35974252 -0.52968526 1.200411349 0.03452872 0.654487711

标题向左移动。另外,如果我想在输出文件中包含 df 的所有前 5 列,该怎么做?

最后,请您指出我上面提到的Zscore方法计算与其他问题中讨论的比例函数之间的区别吗?

【问题讨论】:

  • R 中的很多东西都是矢量化的,包括减法和除法等基本的东西。
  • 所以?这有什么关系?感谢您的详细说明。
  • 我错过了。现在我做到了。谢谢@akrun
  • 绿色复选标记是否应仅用于最佳解决方案 - 请告知?

标签: r loops optimization


【解决方案1】:

我们可以使用matrixStats中的rowSds,一步完成计算。

library(matrixStats)
dfN <- df[6:ncol(df)]
(dfN-rowMeans(dfN))/(rowSds(as.matrix(dfN)))[row(dfN)]
#      Sample1     Sample2    Sample3     Sample4    Sample5
#1 -0.21215364 -1.04807418 -0.5201968  0.18276242  1.5976622
#2 -0.78045398 -1.06127680  0.5418697 -0.10044970  1.4003108
#3 -0.21650630 -0.89031430 -0.4500879 -0.15586480  1.7127733
#4 -1.06493266 -1.01341528  0.3953439  1.20644023  0.4765639
#5  0.02537058 -1.11905074 -0.8610247  0.75908324  1.1956216
#6 -1.35974252 -0.52968526  1.2004113  0.03452872  0.6544877
#7  1.66627789  0.01983708 -0.1342732 -0.79815548 -0.7536863
#8 -1.34013679  0.98280311  0.9828031 -0.11700084 -0.5084686

或者base R唯一的方法是

res <- t(scale(t(dfN)))
attributes(res)[3:4] <- NULL

【讨论】:

  • 行得通!但是当我输出 Zmatrix=(dfN-rowMeans(dfN))/(rowSds(as.matrix(dfN)))[row(dfN)] 时,我仍然让标题向左移动。另外,我怎样才能从最初的 df 中添加剩余的列。请注意,代码中的 6 应该是 5 以匹配上面的数据。
  • @BioProgram 可能是因为您数据中的一列是row.names,我将其用作第一列。你可以cbindcbind(df[1:5], res) 其中res &lt;- (dfN-rowMeans(dfN))..
  • 很高兴了解 cbind。但是当我使用它时,我仍然错过了第一列。
  • @BioProgram 那么,您可能在初始数据集中没有该列。相反,它会 row.names 。因此,data.frame(rn= row.names(df), df[1:5], res)
  • 是的,这非常有效。或者,我可以从 df 分配的初始行中删除 row.names=1 并将 1 添加到数据帧限制。
【解决方案2】:

假设你将原始数据读入一个名为df的数据框,在这个基础包中,你可以使用apply函数得到如下结果:

resultMatrix <- apply(df[, 6:10], 1, function(x) (x - mean(x)) / sd(x))

要将其转换为 ID 列与原始绑定的数据框,您可以执行以下操作:

cbind(df$GeneID, data.frame(t(resultMatrix)))

【讨论】:

  • 虽然这有效,但不会自动设置 df$GeneID 的列名。此外,您能否请更多 apply(df[, 6:10], 1, function(x) (x - mean(x)) / sd(x)) ?我知道您正在将函数应用到最后df 列,但是函数之前的“1”呢?那是为了什么?
  • 您可能希望通过在 r 控制台中执行“?apply”来查看应用功能的帮助页面的详细信息。 1 表示“行明智”。您可以按列提供 2。至于第一列名称,您可以使用 'colnames()' 或 names(output)[1]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-09
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
  • 2020-10-11
  • 1970-01-01
  • 2022-08-14
相关资源
最近更新 更多