【问题标题】:looping through data.frames循环遍历 data.frames
【发布时间】:2015-10-12 12:40:05
【问题描述】:

我有 2 个数据帧

> head(cont)
                    old_pert     cmap_name       conc   perturb_geo        t1        t2        t3        t4        t5
1 5202764005789148112904.A02     estradiol 0.00000001 GSM119257 GSM119218 GSM119219 GSM119221 GSM119222 GSM119223
2 5202764005789148112904.A01 valproic acid 0.00050000 GSM119256 GSM119218 GSM119219 GSM119221 GSM119222 GSM119223

> head(expression)[1:3,1:8]
          GSM118911 GSM118912 GSM118913 GSM118723 GSM118724 GSM118725 GSM118726 GSM118727
1007_s_at     387.6     393.2     290.5     378.6     507.8     383.7     288.8     451.9
1053_at        56.4      53.5      32.8      39.0      71.5      47.3      46.0      50.1
117_at          6.3      33.6      19.2      17.6      20.3      15.0       7.1      43.1

我想应用一个循环来做:

for(i in 1:nrow(cont)){

首先从cont 中取一些值,这些值将在前面使用

vehicle <- cont[i, 5:9]
perturb <- cont[i, 4]
col_name <- paste(cont[i, 2], cont[i, 3], sep = '_') #estradiol_.00001
tmp <- sum(expression[,which(colnames(expression) == vehicle)])/5
tmp2 <- expression[,which(colnames(expression) == perturb)]
tmp3 <- tmp/tmp2
div <- cbind(div, tmp3)
colnames(div)[i + 1] <- col_name
}

expression 那里获取col.names == vehicle &amp; perturb 中的那些列并应用除法。

div <- expression$vehicle / expression$perturb #I'm not getting how I can pass here the value in `vehicle` and `perturb`

为这个新变量分配一个列名,该列名应该是drug_nameconcentration 的组合

col.names(div) <- drug_name_concentration

为其分配表达式的row.names:

row.names(div) <- row.names(expression)

所以这个过程将迭代 271 次 (nrow(cont) = 271) 并且每次新的分割列将 cbind 到我之前的 div。因此最终结果将是:

                arachidonic acid_0.000010     oligomycin_0.000001 .........
1007_s_at            0.45                      0.30
1053_at              1.34                      0.65
117_at               0.11                      0.67
.....
.....

我的头脑中的逻辑很清楚,但我不知道该怎么做。感谢您的帮助。

【问题讨论】:

    标签: r for-loop dataframe


    【解决方案1】:

    您没有在循环中正确分配变量。下面是一个示例循环,它将正确遍历分配变量的每一行。例如第一个循环 i == 1,注意我改变了列名的生成方式。

    for(i in 1:nrow(cont)){
           vehicle <- cont[i, 3]
           perturb <- cont[i, 4]
           col_name <- paste(cont[i, 5], cont[i, 6], sep = '_')
        }
    

    然后使用这些变量名搜索相应的列,然后您可以使用:

    df[,which(colnames(df) == x)]
    

    方法,其中 df 是数据框,x 是变量。

    因此,

    div <- data.frame(row.names(expression))
    for(i in 1:nrow(cont)){
           vehicle <- cont[i, 3]
           perturb <- cont[i, 4]
           col_name <- paste(cont[i, 5], cont[i, 6], sep = '_')
    
           tmp <- expression[,which(colnames(expression) == vehicle)]/
                        expression[,which(colnames(expression) == perturb)]
    
           div <- cbind(div, tmp)
    
           colnames(div)[i + 1] <- col_name
        }
    
        div <- div[,-1]
        row.names(div) <- row.names(expression)
    

    发生的情况是它遍历每一行,在找到这些列之前将值分配给变量,然后简单地除以结果向量。

    然后它按列绑定到循环之前创建的 div 数据框,其中包含表表达式中的行名。

    最后,重命名列名,并在完成循环后重命名行名并删除具有现在冗余值的第一列。

    编辑 - 问题已更改

    改变#1

    vehicle <- cont[i, 5:9]
    

    vehicle <- cont[i, c(5:9)] ## note c()
    

    更改 #2

    tmp <- sum(expression[,which(colnames(expression) == vehicle)])/5
    

    tmp <- sum(expression[,which(colnames(expression) %in% vehicle)])/5
    

    最终编辑

    完整的工作功能:

    for(i in 1:nrow(cont)){
    
      perturb <- cont[i, 4]
      col_name <- paste(cont[i, 2], cont[i, 3], sep = '_')
      vehicle <- cont[i, c(5:9)]
      vehicle <- unname(unlist(vehicle[1,]))
      tmp <- expression[,which(colnames(expression) %in% vehicle)]
      row_tots <- as.data.frame(rowSums(tmp))
      row_tots <- row_tots/5
    
      tmp <- row_tots/expression[,which(colnames(expression) == perturb)]
      div <- cbind(div, tmp)
      colnames(div)[i + 1] <- col_name
    }
    div <- div[,-1]
    row.names(div) <- row.names(expression)
    

    【讨论】:

    • 谢谢你。它起作用了..我想知道这个东西是如何工作的:在某些情况下,col_name &lt;- paste(cont[i, 5], cont[i, 6], sep = '_') 有两个实例的相同名称,并且这段代码通过命名“metformin_0.00001”和“metformin_0.00001.1”来处理它。你能解释一下为什么以及如何发生吗?
    • 您可以尝试使用col_names &lt;- c() 创建一个空向量,然后在循环中col_names &lt;- c(col_names, paste(cont[i, 5], cont[i, 6], sep = '_')) 显然删除循环中col_names 的另一个实例。然后在循环之后和div &lt;- div[,-1]之后通过colnames(div) &lt;- col_names分配列名
    • 好的,谢谢。你能告诉我perturb包含多于1列并且我想取perturb = sum of columns / no.of columns然后划分control / perturb的情况可能的解决方案吗?
    • 取决于您是否知道它将是多少列。如果情况有所不同,那么您可能会想要编写一个处理该问题的函数。上面的函数处理已知数量的列。除了这个细节之外,在df[,which(colnames(df) == x)] 中,您可以使用 OR 运算符| 使其变为df[,which(colnames(df) == x | colnames(df) == y)],您甚至可以将其包装在sum()/nrow() 函数中以获取值。然而,这会给你一个单一的价值,我猜这就是你想要的意思。
    • 现在在每种情况下我都必须为车辆取 5 列(我正在这样做:vehicle &lt;- cont[i, 5:9]),将它们的值相加并除以 5:它将是 vehicle(我正在做的事情是:tmp &lt;- sum(expression[,which(colnames(expression) == vehicle)])/5) 但它不起作用。 @amwill04
    猜你喜欢
    • 2020-10-16
    • 2011-02-23
    • 1970-01-01
    • 2020-11-17
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    相关资源
    最近更新 更多