【问题标题】:Find max of rows from specific columns and extract column name and corresponding row value from another column从特定列中查找最大行数并从另一列中提取列名和相应的行值
【发布时间】:2017-08-18 12:13:41
【问题描述】:

这是我拥有的一个数据结构:

structure(list(UDD_beta = c(1.17136554204268, 0.939587997289016
), UDD_pval = c(0, 0), UDD_R.sq = c(0.749044972637797, 0.516943886705951
), SSX_beta = c(1.05356804780772, 0.927948300464624), SSX_pval = c(0, 
0), SSX_R.sq = c(0.60226298037862, 0.629111666509209), SPP_beta = c(0.675765151939885, 
0.516425218613404), SPP_pval = c(0, 0), SPP_R.sq = c(0.479849538274406, 
0.378266618442121), EEE_beta = c(0.690521022226874, 0.639380962824289
), EEE_pval = c(0, 0), EEE_R.sq = c(0.585610742768951, 0.676073352909597
)), .Names = c("UDD_beta", "UDD_pval", "UDD_R.sq", "SSX_beta", 
"SSX_pval", "SSX_R.sq", "SPP_beta", "SPP_pval", "SPP_R.sq", 
"EEE_beta", "EEE_pval", "EEE_R.sq"), row.names = c("DDK", "DDL"
), class = "data.frame")

我想获取R.sq 列,并为每一行找到最大值和最大值的列名。然后取对应的beta。预期输出:

    Name Value
DDK UDD 1.17136554204268
DDL EEE 0.690521022226874

抱歉,第二个期望值应该是0.639380962824289

【问题讨论】:

  • 现在我再次阅读,似乎错误的值是第一个(该列中没有R.sq
  • 有 UDD_R.sq 列。还是您指的是其他问题?
  • 但是我想提取UDD_beta ))

标签: r dataframe


【解决方案1】:

我们可以使用max.col。使用grep 对感兴趣的列进行子集化,即具有“R.sq”的列,然后使用max.col 获取max 值的列索引。使用它来获取列名以及对应于特定行的值(row/column 索引)

i1 <- grep("R.sq", names(df1))
i2 <- max.col(df1[i1], "first")
i3 <- grep("beta", names(df1))
res <- data.frame(Names = sub("_.*", "", names(df1)[i1][i2]), 
               Value = df1[i3][cbind(1:nrow(df1), i2)])
row.names(res) <- row.names(df1)

【讨论】:

  • 这不同意OP。我认为我的也没有,但我不确定 OP 想要什么
  • @Sotos 我不明白逻辑。如果它基于“beta”列,为什么这两个值来自同一行。不应该是0.63981
  • @akrun OP 提供了错误的预期输出(这是我的猜测)
【解决方案2】:
sub_data <- data[grep("R.sq", colnames(data))]
colnames(sub_data) <- gsub("_R.sq", "", colnames(sub_data))
sub_data$Name <- NA
sub_data$Value <- NA
for (i in 1:nrow(sub_data)){
  sub_data$Name[i] <- names(sub_data[i,])[which.max(apply(sub_data[i,], 2, max))]
  sub_data$Value[i] <- max(data[grep(paste0(sub_data$Name[i], "_beta"), colnames(data))], na.rm=T)
}
sub_data[c("Name", "Value")]
#    Name    Value
#DDK  UDD 1.171366
#DDL  EEE 0.690521

【讨论】:

    【解决方案3】:

    您可以使用tidyverse 方法,通过gather将您的df 转换为long 并过滤R.sq vars 和最大值,即

    library(tidyverse)
    
    df %>% 
     rownames_to_column('ID') %>% 
     gather(var, val, -ID) %>% 
     filter(grepl('R.sq|beta', var)) %>% 
     group_by(ID) %>% 
     mutate(max1=as.integer(val == max(val[grepl('R.sq', var)]))) %>% 
     group_by(ID, grp = sub('_.*', '', var)) %>% 
     filter(!all(max1 == 0) & grepl('beta', var)) %>% 
     ungroup() %>% select(-c(max1, grp))
    

    给出,

    # A tibble: 2 x 3
         ID      var      val
      <chr>    <chr>    <dbl>
    1   DDK UDD_beta 1.171366
    2   DDL EEE_beta 0.639381
    

    【讨论】:

      【解决方案4】:
      # Need ID for all possible betas and Rsq
      ID <- gsub("_R.sq", "", grep("_R.sq$", names(INPUT), value = TRUE))
      dummy <- function(x) {
          # Find out which Rsq is largest
          i <- ID[which.max(x[paste0(ID, "_R.sq")])]
          # Extract beta for largest Rsq
          data.frame(Name = i, Value = x[paste0(i, "_beta")])
      }
      do.call("rbind", apply(INPUT, 1, dummy))
      

      【讨论】:

      • 即使现在我编辑了我的答案,我们得到了相同的结果,但他们不同意 OP 输出。
      • @Sotos 你或我的答案怎么与 OP 的输出不一致?
      • 输出的第二个值是 0.6905... - 对应于第一行 beta.. 你的(和我的)不是
      • @Sotos OP 提供了错误的预期输出(这是我的猜测)
      猜你喜欢
      • 2019-07-23
      • 1970-01-01
      • 2021-05-17
      • 2013-11-26
      • 1970-01-01
      • 2015-01-26
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多