【问题标题】:Finding the Highest Frequencies in multiple columns在多列中查找最高频率
【发布时间】:2018-02-22 17:07:44
【问题描述】:

我有一个包含 10 列和 2000 行的数据框。我的示例数据如下所示:

rs_id   Code    Combination_Ag  A.Ag    Combination_Bg  B.Ag    Combination_Cg  C.Ag
rs_1    0   1:01/1:01   1   13:02/13:02 1   03:04/03:04 6   1:01/1:01   1
rs_1    0   1:01/11:01  2   13:02/49:01 2   03:04/15:02 1   1:01/15:01  1
rs_1    1   1:01/2:01   6   13:02/57:01 1   03:04/7:01  2   1:01/3:01   1
rs_1    2   1:01/2:05:  1   13:02/8:01  1   06:02/06:02 3   1:01/4:04   1
rs_1    2   1:01/24:02  3   14:01/14:02 1   06:02/15:02 1   1:01/4:04   3
rs_2    0   1:01/3:01   1   14:01/7:02  1   06:02/2:02: 1   1:01/4:07   1
rs_2    1   1:01/31:01  1   15:01/15:01 1   06:02/3:03  1   1:01/7:01   2
rs_2    1   11:01/2:01  4   15:01/18:01 1   06:02/3:04  1   10:01/14:01 1
rs_2    2   11:01/25:01 1   15:01/44:02 2   06:02/4:01  1   10:01/3:01  5

我正在尝试找到 rs_id =0、1 和 2 的最高组合(A.Ag、B.Bg C.Ag)。我怎样才能做到这一点? 输出将是

rs_1    0   1:01/11:01   2   13:02/49:01    2   03:04/03:04 6   1:01/1:01   1
rs_1    1   1:01/2:01    6   13:02/57:01    1   03:04/7:01  2   1:01/3:01   1
rs_1    2   1:01/24:02   3   06:02/06:02    3   06:02/15:02 1   1:01/4:04   3
rs_2    0   1:01/3:01    1   14:01/7:02     1   06:02/2:02: 1   1:01/4:07   1
rs_2    1   11:01/2:01   4   15:01/18:01    1   06:02/3:04  1   10:01/14:01 1 
rs_2    2   11:01/25:01  1   15:01/44:02    2   06:02/4:01  1   10:01/3:01  5 

【问题讨论】:

  • “Combination_*”列似乎没有自然顺序,因此选择最高的列会带来问题。期望的结果表明您想要最高的 *.Ag 值和关联的组合在同一行和 rs_id 中。
  • @42-对不起。我只需要根据 *.Ag 计数来识别

标签: r data.table sapply


【解决方案1】:

这种方法将数据从宽格式重塑为长格式(同时融合 两个 度量列),为rs_idCode 的每个唯一组合选择具有顶部 Ag 值的行和variable。最后,结果再次从长格式重新调整为宽格式,并重新排列列顺序以返回预期结果:

library(data.table)
cols <- c("Combination", "Ag")
melt(setDT(DF), measure.vars = patterns("Combination", "[A-D][.]Ag"), 
     value.name = cols)[
       , variable := forcats::lvls_revalue(variable, LETTERS[1:4])][
         , .SD[which.max(Ag)], by = .(rs_id, Code, variable)][
           , dcast(.SD, rs_id + Code ~ variable, value.var = cols)][
             , setcolorder(.SD, c(1:2, as.vector(outer(c(0, 4), 3:6, "+"))))]
   rs_id Code Combination_A Ag_A Combination_B Ag_B Combination_C Ag_C Combination_D Ag_D
1:  rs_1    0    1:01/11:01    2   13:02/49:01    2   03:04/03:04    6     1:01/1:01    1
2:  rs_1    1     1:01/2:01    6   13:02/57:01    1    03:04/7:01    2     1:01/3:01    1
3:  rs_1    2    1:01/24:02    3    13:02/8:01    1   06:02/06:02    3     1:01/4:04    3
4:  rs_2    0     1:01/3:01    1    14:01/7:02    1   06:02/2:02:    1     1:01/4:07    1
5:  rs_2    1    11:01/2:01    4   15:01/15:01    1    06:02/3:03    1     1:01/7:01    2
6:  rs_2    2   11:01/25:01    1   15:01/44:02    2    06:02/4:01    1    10:01/3:01    5

编辑

OP 要求解释最后一个链接的data.table 表达式setcolorder(.SD, c(1:2, as.vector(outer(c(0, 4), 3:6, "+"))))

此表达式按引用对结果的列进行排序,即不进行复制。重塑多个value.vars 时,列按value.var 分组:

melt(setDT(DF), measure.vars = patterns("Combination", "[A-D][.]Ag"), 
     value.name = cols)[
       , variable := forcats::lvls_revalue(variable, LETTERS[1:4])][
         , .SD[which.max(Ag)], by = .(rs_id, Code, variable)][
           , dcast(.SD, rs_id + Code ~ variable, value.var = cols)]
   rs_id Code Combination_A Combination_B Combination_C Combination_D Ag_A Ag_B Ag_C Ag_D
1:  rs_1    0    1:01/11:01   13:02/49:01   03:04/03:04     1:01/1:01    2    2    6    1
2:  rs_1    1     1:01/2:01   13:02/57:01    03:04/7:01     1:01/3:01    6    1    2    1
3:  rs_1    2    1:01/24:02    13:02/8:01   06:02/06:02     1:01/4:04    3    1    3    3
4:  rs_2    0     1:01/3:01    14:01/7:02   06:02/2:02:     1:01/4:07    1    1    1    1
5:  rs_2    1    11:01/2:01   15:01/15:01    06:02/3:03     1:01/7:01    4    1    1    2
6:  rs_2    2   11:01/25:01   15:01/44:02    06:02/4:01    10:01/3:01    1    2    1    5

而 OP 期望输出按 variable 分组。所以所需的列顺序是

c(1, 2, 3, 7, 4, 8, 5, 9, 6, 10)

12 表示 id.var 列。 as.vector(outer(c(0, 4), 3:6, "+"))) 只是一种省去输入3, 7, 4, 8, 5, 9, 6, 10 的方法。

outer(c(0, 4), 3:6, "+")
     [,1] [,2] [,3] [,4]
[1,]    3    4    5    6
[2,]    7    8    9   10
as.vector(outer(c(0, 4), 3:6, "+"))
[1]  3  7  4  8  5  9  6 10

编辑 2

代码可以进一步精简。在c() 内部不需要调用as.vector(),因为c() 将数组转换为向量。所以,而不是

c(1:2, as.vector(outer(c(0, 4), 3:6, "+")))

我们可以写

c(1:2, outer(c(0, 4), 3:6, "+"))

数据

请注意,我已经完成了最后两列缺少的列标题。

library(data.table)
DF <- fread(
  "rs_id   Code    Combination_Ag  A.Ag    Combination_Bg  B.Ag    Combination_Cg  C.Ag   Combination_Dg  D.Ag
rs_1    0   1:01/1:01   1   13:02/13:02 1   03:04/03:04 6   1:01/1:01   1
rs_1    0   1:01/11:01  2   13:02/49:01 2   03:04/15:02 1   1:01/15:01  1
rs_1    1   1:01/2:01   6   13:02/57:01 1   03:04/7:01  2   1:01/3:01   1
rs_1    2   1:01/2:05:  1   13:02/8:01  1   06:02/06:02 3   1:01/4:04   1
rs_1    2   1:01/24:02  3   14:01/14:02 1   06:02/15:02 1   1:01/4:04   3
rs_2    0   1:01/3:01   1   14:01/7:02  1   06:02/2:02: 1   1:01/4:07   1
rs_2    1   1:01/31:01  1   15:01/15:01 1   06:02/3:03  1   1:01/7:01   2
rs_2    1   11:01/2:01  4   15:01/18:01 1   06:02/3:04  1   10:01/14:01 1
rs_2    2   11:01/25:01 1   15:01/44:02 2   06:02/4:01  1   10:01/3:01  5"
)

【讨论】:

  • 即将发布非常相似的内容:-)
  • 不使用lvls_revalue-函数,您也可以只使用variable := LETTERS[1:4][variable](这是您的方法和我的方法之间的唯一区别;-))
  • @jaap 确实有很好的改进。我已经习惯使用forcats 包来处理它发生的因素,我忘记了简单的基本 R 方式。
  • 非常感谢您的回答。 setcolorder(.SD, c(1:2, as.vector(outer(c(0, 4), 3:6, "+"))))]。你能解释一下这条线吗?
  • @MSM 我已按要求添加了解释。
猜你喜欢
  • 1970-01-01
  • 2019-04-03
  • 1970-01-01
  • 2021-12-28
  • 2017-07-01
  • 1970-01-01
  • 2013-04-12
  • 1970-01-01
  • 2011-05-07
相关资源
最近更新 更多