R:处理循环内的数据

时间:2015-02-16 15:00:31

标签: r loops

下面,我使用提供的示例数据运行循环,将必要的项目附加到geneexptest,并在循环内进一步处理。但是,在构建dfs时,我希望每次运行的端点都为data.frame(geneexptotal,...),如图所示。问题是,它似乎在geneexptestapp以某种方式停止,并在每轮中将其输出到dfs。请让我知道如何将其余的循环包含在输出中。

gex <- data.frame("sample" =  c("BIX","HEF","TUR","ZOP","VAG","JUF","FED","MEQ","YIF","HRB","LOP","LIX","COT","DRP","KFC","TUY","DOG","KEX","RAV","UEH"), 
                  "TCGA-F4-6703-01" = runif(20, -1, 1),
                  "TCGA-DM-A28E-01" = runif(20, -1, 1),
                  "TCGA-AY-6197-01" = runif(20, -1, 1),
                  "TCGA-A6-5657-01" = runif(20, -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(20, -1, 1),
                  "TCGA-AA-3663-11" = runif(20, -1, 1),
                  "TCGA-AD-6901-01" = runif(20, -1, 1),
                  "TCGA-AZ-2511-01" = runif(20, -1, 1),
                  "TCGA-A6-A567-01" = runif(20, -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)))

    dfs <- lapply(listx, function(colName) {
      do.call(rbind, lapply(seq(nrow(mxy)), function(i) {
        zvalues <- zScore(gex[i,colName], mxy[i,])
        geneexptest <- data.frame(gex$sample[i], zvalues, row.names = NULL, stringsAsFactors = TRUE)
        geneexptest$zvalues <- as.numeric(as.character(geneexptest$zvalues))
        is.na(geneexptest) <- sapply(geneexptest, is.infinite)
        geneexptestapp <- na.omit(geneexptest)
        geneexptestorder <- geneexptestapp[order(geneexptestapp$zvalues, decreasing = FALSE, na.last = NA), ]
        geneexpa <- geneexptestorder[1:((0.05)*nrow(geneexptest)),]
        geneexpz <- geneexptestorder[(nrow(geneexptestorder)-((0.05)*nrow(geneexptest))):nrow(geneexptestorder),]
        geneexptotal <- rbind(geneexpa, geneexpz)
        data.frame(geneexptotal$gex.sample, row.names = NULL, stringsAsFactors = TRUE)
      }))
    })

1 个答案:

答案 0 :(得分:0)

您的代码实际上运行正常。由于您正在进行一些数据管理,您只会有意想不到的输出。我打破了你的代码以帮助提高可读性。我创建了两个新函数fun1和fun2 - fun2是你的内部函数,fun1是外部函数。 fun2将colName作为参数传递给它。

fun2 = function(i,colName) {
  zvalues <- zScore(gex[i,colName], mxy[i,])
  geneexptest <- data.frame(gex$sample[i], zvalues, row.names = NULL, stringsAsFactors = TRUE)
  geneexptest$zvalues <- as.numeric(as.character(geneexptest$zvalues))
  is.na(geneexptest) <- sapply(geneexptest, is.infinite)
  geneexptestapp <- na.omit(geneexptest)
  geneexptestorder <- geneexptestapp[order(geneexptestapp$zvalues, decreasing = FALSE, na.last = NA), ]
  geneexpa <- geneexptestorder[1:((0.05)*nrow(geneexptest)),]
  geneexpz <- geneexptestorder[(nrow(geneexptestorder)-((0.05)*nrow(geneexptest))):nrow(geneexptestorder),]
  geneexptotal <- rbind(geneexpa, geneexpz)
  data.frame(geneexptotal, row.names = NULL, stringsAsFactors = TRUE)
}

fun1 = function(colName) {
  do.call(rbind, lapply(seq(nrow(mxy)), fun2, colName=colName))
}

dfs <- lapply(listx, fun1)

因此,listx中有两个列名 - 让我们从第一个开始,TCGA_DM_A28E_01。所以,我们打电话给fun1("TCGA_DM_A28E_01")。对于fun2,这将是rbind每个5(nrow(mxy) = 5)次迭代。

所以,让我们从i=1开始(我们现在在fun2中)。您从gex获取一个值,从mxy获取一行,将它们放在zScore中,其值为-0.6955057。然后,您创建一行data.frame并对zvalues列执行一些操作。所以我们有:

> geneexptest
  gex.sample.i.    zvalues
1           BIX -0.6955057

进行一些检查并确认没有任何东西是无限的,如果是,则将其删除。所以现在我们有:

> geneexptestapp
  gex.sample.i.    zvalues
1           BIX -0.6955057

现在您对1行数据帧进行了一些排序。没有什么变化。这就是nrow(geneexptest) = 1问题所在,因此对于geneexpa,您要求的行1:.051geneexpz {&#39}}相同39;重新询问.95:10.95。没有分数行。这导致:

> geneexpa;geneexpz
  gex.sample.i.    zvalues
1           BIX -0.6955057
[1] gex.sample.i. zvalues      
<0 rows> (or 0-length row.names)

rbind并作为数据框返回。在这种情况下,它产生单行数据帧。 fun1生成其中的5个并将它们绑定在一起,为您提供5行data.frame。 dfs是其中2个的列表。

您的代码建议您希望获得超过1行(您的乘法建议至少为20行),但只有1行。这里的示例都没有完成,或者您需要重新思考什么&#39;发生在fun2。

<强>更新

好的,根据您的更新要求,请考虑以下功能:

getExtremeValues = function(x,p=0.05){
  z = x[,2]
  n = ceiling(nrow(x)*p)
  r = x[order(z),1]
  return(as.character(r[c(1:n,length(r):(length(r)-n+1))]))
}

您将此函数传递给数据框(x),告诉它哪个列具有您的z值(默认情况下c = 2)以及您想要的顶部和底部比例(默认情况下p = 0.05)。然后它返回第一列,其中z值位于顶部和底部百分比。

如何使这一切工作:

fun2 = function(i,colName) {
  zvalues <- zScore(gex[i,colName], mxy[i,])
  geneexptest <- data.frame(gex$sample[i], zvalues, row.names = NULL, stringsAsFactors = TRUE)
  geneexptest$zvalues <- as.numeric(as.character(geneexptest$zvalues))
  is.na(geneexptest) <- sapply(geneexptest, is.infinite)
  return(na.omit(geneexptest))
}

fun1 = function(colName) {
  getExtremeValues(do.call(rbind, lapply(seq(nrow(mxy)), fun2, colName=colName)))
}

dfs <- lapply(listx, fun1)

返回:

> dfs
[[1]]
[1] "BIX" "TUY"

[[2]]
[1] "BIX" "TUR"

鉴于有20个样本,1个位于前5%,1个位于底部5%,listx中列出了两个列名,因此返回了4个样本。