【问题标题】:grouping dataframe rows by factor and by function - output complete original dataframe row按因子和功能分组数据帧行 - 输出完整的原始数据帧行
【发布时间】:2011-10-10 19:38:44
【问题描述】:

我的第一篇文章,我对 R 很陌生,所以这可能是一个 lob。不过,我已经到处寻找解决方案,所以我终于发帖寻求帮助。如果我需要澄清或提供更多信息,请告诉我。

我有一个大数据框,如下所示:

numReads length    name2
0        7384      Ssxb2
7904     93237     St5
3438     12969     Taf9b
0        996       Tas2r138
0        882       Tas2r143
0        960       Tas2r144
0        6761      Tbx10
8125     43804     Tdrd1
8124     43738     Tdrd1
8102     39301     Tdrd1
1227     9286      Thnsl1

如何按第三列(name2)对数据进行分组,找到 numReads 的 max() 值,并保持关联的长度值?

我的理想输出是上述数据,其中包含与“Tdrd1”相关联的两行,其中不包含该因子水平的最大值(具有 8124 和 8102 值的行)。

我尝试过tapply()by()aggregate()。他们都不能为我提供正确的输出。

提前致谢。

在比预期快得多的 cmets 之后进行编辑。谢谢!

理想的示例结果如下所示

numReads  length  name2
0        7384      Ssxb2
7904     93237     St5
3438     12969     Taf9b
0        996       Tas2r138
0        882       Tas2r143
0        960       Tas2r144
0        6761      Tbx10
8125     43804     Tdrd1
1227     9286      Thnsl1

看来我在这里有两个问题。第一个是根据一个因素对数据进行分组。第二个是如何在组上计算一个函数,但在计算出所选函数后输出整行。

我喜欢聚合() 后跟合并() 的想法。但是,merge() 函数如何知道原始行中的哪一行可以根据公因子水平获取“长度”值?

数据是基于转录注释的基因表达数据的快照。我正在尝试为关联的“name2”选择表达最高的成绩单(以 numReads 而言)。我需要下游标准化的长度数据。

在尝试使用 ROLO 非常有用的建议后进行编辑。再次感谢!

也感谢 Chase 和 daroczig 的帮助

所以我尝试使用 ddply() 方法将我的数据帧按“name2”拆分,按读取次数降序排序,然后选择第一行。这有效地为我提供了每个组的最大“name2”值,并保留了我所有的原始信息,尤其是长度。

不幸的是,我正在尝试在 >34,000 行的数据帧上执行此操作。它适用于 ~1000 行,甚至 ~5000 行,但是当我将整个数据集提供给它时​​会崩溃。

我尝试使用 .parallel 选项,但失败并出现以下错误:

Loading required package: foreach
Error: foreach package required for parallel plyr operation

我也尝试使用 .progressbar 选项来监控操作。进度条达到 100%,但操作从未完成。

关于如何将此操作应用于我的完整数据集的任何想法?

【问题讨论】:

  • 您能否通过给出示例结果来澄清一下?我不完全理解你的意思。

标签: r selection grouping subset r-factor


【解决方案1】:

使用plyr对name2进行拆分,然后对numReads进行反向排序并选择第一行:

require(plyr)
ddply(df, "name2", function(dat) {
    dat[order(dat$numReads, decreasing=TRUE), ][1,]
})

  numReads length    name2
1        0   7384    Ssxb2
2     7904  93237      St5
3     3438  12969    Taf9b
4        0    996 Tas2r138
5        0    882 Tas2r143
6        0    960 Tas2r144
7        0   6761    Tbx10
8     8125  43804    Tdrd1
9     1227   9286   Thnsl1

【讨论】:

    【解决方案2】:

    我可能无法准确了解您的需求,但我认为您希望从数据库中获取在numReadsname2 的每个级别中具有最高值的行。这可以很容易地完成,例如。使用aggregate 和更高版本的merge

    您的演示数据集:

    df  <- structure(list(numReads = c(0L, 7904L, 3438L, 0L, 0L, 0L, 0L, 
    8125L, 8124L, 8102L, 1227L), length = c(7384L, 93237L, 12969L, 
    996L, 882L, 960L, 6761L, 43804L, 43738L, 39301L, 9286L), name2 = structure(c(1L, 
    2L, 3L, 4L, 5L, 6L, 7L, 8L, 8L, 8L, 9L), .Label = c("Ssxb2", 
    "St5", "Taf9b", "Tas2r138", "Tas2r143", "Tas2r144", "Tbx10", 
    "Tdrd1", "Thnsl1"), class = "factor")), .Names = c("numReads", 
    "length", "name2"), class = "data.frame", row.names = c(NA, -11L
    ))
    

    让我们通过name2max函数聚合数据框:

    > df.a <- aggregate(numReads ~ name2, df, max)
    > df.a
         name2 numReads
    1    Ssxb2        0
    2      St5     7904
    3    Taf9b     3438
    4 Tas2r138        0
    5 Tas2r143        0
    6 Tas2r144        0
    7    Tbx10        0
    8    Tdrd1     8125
    9   Thnsl1     1227
    

    并将length的原始值合并到数据框(df.a):

    > merge(df.a, df)
         name2 numReads length
    1    Ssxb2        0   7384
    2      St5     7904  93237
    3    Taf9b     3438  12969
    4 Tas2r138        0    996
    5 Tas2r143        0    882
    6 Tas2r144        0    960
    7    Tbx10        0   6761
    8    Tdrd1     8125  43804
    9   Thnsl1     1227   9286
    

    希望我没有误解你的问题!

    【讨论】:

    • 合并函数如何知道要选择原始numRead行中的哪一行?
    • @sigalphroy:如果您在聚合表中有 name2numReads 的唯一组合,AFAIK merge 将发挥作用。见:?merge
    【解决方案3】:

    这里似乎有两个不同的问题。第一个可以用plyr包解决:

    library(plyr)
    txt <- "numReads length    name2
    
    0   7384    Ssxb2
    7904  93237      St5
    3438  12969    Taf9b
    0    996 Tas2r138
    0    882 Tas2r143
    0    960 Tas2r144
    0   6761    Tbx10
    8125  43804    Tdrd1
    8124  43738    Tdrd1
    8102  39301    Tdrd1
    1227   9286   Thnsl1
    "
    
    dat <- read.table(textConnection(txt), header = TRUE)
    
    ddply(dat, "name2", summarize, max = max(numReads))
    

    给你:

         name2  max
    1    Ssxb2    0
    2      St5 7904
    3    Taf9b 3438
    4 Tas2r138    0
    5 Tas2r143    0
    6 Tas2r144    0
    7    Tbx10    0
    8    Tdrd1 8125
    9   Thnsl1 1227
    

    第二个问题似乎可以这样回答:

    dat[dat$name2 == "Tdrd1" & dat$numReads != max(dat$numReads[dat$name2 == "Tdrd1"]),]
    
       numReads length name2
    9      8124  43738 Tdrd1
    10     8102  39301 Tdrd1
    

    提供更多关于您正在尝试做的事情的背景信息,我会进一步详细说明。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多