有没有一种更快的方法可以根据我必须搜索的其他行中的值来解析和编辑一行中的值?

Is there a faster way to parse and edit values in a row based on values in other rows that I have to search for?

我正在尝试通过 R 中的长数据帧进行解析。我正在寻找 tau 列中值大于 0.7 的行。然后我在长格式数据框中找到所有其他行,这些行在 geneID 列中具有相同的名称,在物种列中具有相同的名称,但在组织列中具有不同的名称。我必须检查其中哪些在 log2expression 中具有最高值,然后将该组织的名称放在具有相同 geneID 和物种列的每一行的偏向列中。我有一个 for 循环,但目前它很慢而且很丑陋:

long_tau$biased <- 'general'
for(gRow in 1:nrow(long_tau)) {
  print(gRow)
  if(!is.nan(long_tau$tau[gRow])){
      if(long_tau$tau[gRow] >= 0.7){
        tmpGenes <- long_tau %>% filter_all(any_vars(. %in% c(long_tau$GeneID[gRow]))) %>%
        filter_all(any_vars(. %in% c(long_tau$species[gRow]))) 
        long_tau$biased[gRow] <- tmpGenes[which.max(tmpGenes$log2Expression),]$tissue
  }}
}

我想知道我可以做些什么来提高它的效率。我在想我可以尝试为我放入 tmpGenes 数据框中的所有那些过滤行一次性指定有偏差的列。然后我可以跳过所有与 'general' 具有不同字符串的行,但偏向 column.I 不知道我会怎么做。欢迎提出其他提高效率的想法。

数据如下所示:

GeneID tau species tissue log2Expression biased
Solyc01g005000.3 0.7000207 lyc styungerm 5.40986856 styungerm

每次我制作 tmpGenes 时它都有三行,每个组织一行。

感谢您的帮助。 根据要求使用 dput() 在此处添加了一些行。

structure(list(GeneID = c("Solyc01g005000.3", "Solyc01g005010.4", 
"Solyc01g005020.3", "Solyc01g005030.4", "Solyc01g005040.3", "Solyc01g005050.4", 
"Solyc01g005060.3"), tau = c(0.700020714228337, 0.519089831890165, 
0.527472673446906, 0.513496977771781, NaN, 1, 1), species = c("lyc", 
"lyc", "lyc", "lyc", "lyc", "lyc", "lyc"), tissue = c("styungerm", 
"styungerm", "styungerm", "styungerm", "styungerm", "styungerm", 
"styungerm"), log2Expression = c(5.40986855973033, 3.79990010472802, 
5.94750789262394, 5.27701171052278, 0, 0, 0), specific = c(FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), PME = c(FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE), PMEI = c(FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE), biased = c("styungerm", "general", 
"general", "general", "general", "pollen", "leaf")), row.names = 6:12, class = "data.frame")

tmpGenes 中的行数:

structure(list(GeneID = c("Solyc07g005715.1", "Solyc07g005715.1", 
"Solyc07g005715.1"), tau = c(1, 1, 1), species = c("lyc", "lyc", 
"lyc"), tissue = c("styungerm", "pollen", "leaf"), log2Expression = c(0, 
0.574076953583166, 0), specific = c(FALSE, FALSE, FALSE), PME = c(FALSE, 
FALSE, FALSE), PMEI = c(FALSE, FALSE, FALSE), biased = c("general", 
"general", "general")), row.names = c(NA, -3L), class = "data.frame")

base R 中,考虑ave 计算一个或多个组的聚合。下面的注释使用了类似 lambda 的符号,\(x) 在 R 4.1.0 中引入。对以前的版本使用 function(x)

long_tau <- within(
  long_tau, {
    # CALCULATE MAX log2Expression BY GeneID AND species
    max_log2exp <- ave(log2Expression, GeneID, species, FUN=\(x) max(x, na.rm=TRUE)) 

    # CONDITIONALLY ASSIGN NEW biased COLUMN
    biased <- ifelse(
        log2Expression == max_log2exp & tau >= 0.7 & !is.na(tau), tissue, "general"
    )

    # REMOVE HELPER CALCULATION
    rm(max_log2exp)
  }
)