R:附加到for循环中的数据框
R: Appending to a data frame in a for loop
所以我有这个循环,它会写入多个 csv 文件,每个文件都附加在 运行 的结果之外。正如您在下面看到的,这个特定的循环 运行 是一个统计函数 (zScore),它跨越来自 gex 和 mxy 的子集的每一行,然后发布每一行的结果,然后移动到 gex 的下一个子集。
我的问题是,有没有一种方法可以让我在看起来相同的循环中构建数据框,而不是将附加结果写入 csv 文件?
感谢您的帮助。
gex <- data.frame("sample" = c("BIX","HEF","TUR","ZOP","VAG"),
"TCGA-F4-6703-01" = runif(5, -1, 1),
"TCGA-DM-A28E-01" = runif(5, -1, 1),
"TCGA-AY-6197-01" = runif(5, -1, 1),
"TCGA-A6-5657-01" = runif(5, -1, 1))
colnames(gex) <- gsub("[.]", "_",colnames(gex))
listx <- c("TCGA_DM_A28E_01","TCGA_A6_5657_01")
mxy <- data.frame("TCGA-AD-6963-01" = runif(5, -1, 1),
"TCGA-AA-3663-11" = runif(5, -1, 1),
"TCGA-AD-6901-01" = runif(5, -1, 1),
"TCGA-AZ-2511-01" = runif(5, -1, 1),
"TCGA-A6-A567-01" = runif(5, -1, 1))
colnames(mxy) <- gsub("[.]", "_",colnames(mxy))
zScore <- function(x,y)((as.numeric(x) - as.numeric(rowMeans(y,na.rm=T)))/as.numeric(sd(y,na.rm=T)))
for(i in seq(nrow(mxy))){
for(colName in listx){
zvalues <- zScore(gex[i,colName],
mxy[i,])
geneexptest <- data.frame(gex$sample[i], zvalues, row.names = NULL,
stringsAsFactors = TRUE)
write.table(geneexptest, file = paste0(colName, "mxyinput", ".csv"),
row.names=FALSE, col.names=FALSE, quote=F,
sep = ",", dec = ".", append=(i > 1))
}
}
在您发布的代码中,listx
的每个元素都有一个 csv 文件,并且您正在将多行逐行写入这些文件中的每一个。相反,您可以为 listx
的每个元素创建一个数据框,并通过一次调用 write.table
.
写出每个元素
dfs <- lapply(listx, function(colName) {
do.call(rbind, lapply(seq(nrow(mxy)), function(i) {
zvalues <- zScore(gex[i,colName], mxy[i,])
data.frame(gex$sample[i], zvalues, row.names = NULL, stringsAsFactors = TRUE)
}))
})
dfs
# [[1]]
# gex.sample.i. zvalues
# 1 BIX 1.1105593
# 2 HEF 0.5451948
# 3 TUR -1.4060388
# 4 ZOP -1.4218218
# 5 VAG 0.2780513
#
# [[2]]
# gex.sample.i. zvalues
# 1 BIX 2.0607386
# 2 HEF 1.6703912
# 3 TUR 1.3249181
# 4 ZOP 0.8865058
# 5 VAG 1.5289732
现在您可以使用 write.table
.
输出每一列的完整数据框
在对 rbind
的一次调用中将所有数据帧组合在一起比在每次循环迭代中调用 rbind
效率更高;有关详细信息,请参见 The R Inferno 的第 2 圈。
所以我有这个循环,它会写入多个 csv 文件,每个文件都附加在 运行 的结果之外。正如您在下面看到的,这个特定的循环 运行 是一个统计函数 (zScore),它跨越来自 gex 和 mxy 的子集的每一行,然后发布每一行的结果,然后移动到 gex 的下一个子集。
我的问题是,有没有一种方法可以让我在看起来相同的循环中构建数据框,而不是将附加结果写入 csv 文件?
感谢您的帮助。
gex <- data.frame("sample" = c("BIX","HEF","TUR","ZOP","VAG"),
"TCGA-F4-6703-01" = runif(5, -1, 1),
"TCGA-DM-A28E-01" = runif(5, -1, 1),
"TCGA-AY-6197-01" = runif(5, -1, 1),
"TCGA-A6-5657-01" = runif(5, -1, 1))
colnames(gex) <- gsub("[.]", "_",colnames(gex))
listx <- c("TCGA_DM_A28E_01","TCGA_A6_5657_01")
mxy <- data.frame("TCGA-AD-6963-01" = runif(5, -1, 1),
"TCGA-AA-3663-11" = runif(5, -1, 1),
"TCGA-AD-6901-01" = runif(5, -1, 1),
"TCGA-AZ-2511-01" = runif(5, -1, 1),
"TCGA-A6-A567-01" = runif(5, -1, 1))
colnames(mxy) <- gsub("[.]", "_",colnames(mxy))
zScore <- function(x,y)((as.numeric(x) - as.numeric(rowMeans(y,na.rm=T)))/as.numeric(sd(y,na.rm=T)))
for(i in seq(nrow(mxy))){
for(colName in listx){
zvalues <- zScore(gex[i,colName],
mxy[i,])
geneexptest <- data.frame(gex$sample[i], zvalues, row.names = NULL,
stringsAsFactors = TRUE)
write.table(geneexptest, file = paste0(colName, "mxyinput", ".csv"),
row.names=FALSE, col.names=FALSE, quote=F,
sep = ",", dec = ".", append=(i > 1))
}
}
在您发布的代码中,listx
的每个元素都有一个 csv 文件,并且您正在将多行逐行写入这些文件中的每一个。相反,您可以为 listx
的每个元素创建一个数据框,并通过一次调用 write.table
.
dfs <- lapply(listx, function(colName) {
do.call(rbind, lapply(seq(nrow(mxy)), function(i) {
zvalues <- zScore(gex[i,colName], mxy[i,])
data.frame(gex$sample[i], zvalues, row.names = NULL, stringsAsFactors = TRUE)
}))
})
dfs
# [[1]]
# gex.sample.i. zvalues
# 1 BIX 1.1105593
# 2 HEF 0.5451948
# 3 TUR -1.4060388
# 4 ZOP -1.4218218
# 5 VAG 0.2780513
#
# [[2]]
# gex.sample.i. zvalues
# 1 BIX 2.0607386
# 2 HEF 1.6703912
# 3 TUR 1.3249181
# 4 ZOP 0.8865058
# 5 VAG 1.5289732
现在您可以使用 write.table
.
在对 rbind
的一次调用中将所有数据帧组合在一起比在每次循环迭代中调用 rbind
效率更高;有关详细信息,请参见 The R Inferno 的第 2 圈。