【问题标题】:Aggregate/sum/tally values based on identical column names or separate df in R基于相同的列名或 R 中的单独 df 聚合/求和/计数值
【发布时间】:2018-12-11 19:39:09
【问题描述】:

我一直在尝试几种不同的方式(聚合、colSum、tally 等),但我很挣扎。

我有一个包含样本结果的大型数据集(100 列,1,000,000 行),其中我已将各个样本名称替换为它们所属类别的名称。 (我需要按类别统计每个数据点的总数。

Sequence   position  cat1  cat1  cat2  cat2  cat2  cat3  cat3
abfsgdfy   a         0     1     0     1     0     1     1
abfsgdfy   b         0     0     1     1     1     1     0
dgdtecgd   b         1     1     1     0     0     0     0

我知道不希望有相同的列名,所以我一直在尝试转置数据,然后使用它。但这也没有让我走得太远。

我正在寻找的输出将是:

Sequence  position  cat1  cat2  cat3
abfsgdfy   a        1     1     2 
abfsgdfy   b        0     3     1
dgdtecgd   b        2     1     0

如果有帮助,我有一个表格可以将样本名称转换为更大的类别组:

Type    Name
cat1    sample1
cat1    sample2
cat2    sample3
cat2    sample4
cat2    sample5
cat3    sample6
cat3    sample7

感谢您的帮助!

【问题讨论】:

    标签: r sum aggregate


    【解决方案1】:

    这个怎么样?

    library("tidyverse")
    df = tibble(c("abfsgdfy", "abfsgdfy", "dgdtecgd"),
                    c("a", "b", "b"),
                    c(0, 0, 1),
                    c(1, 0, 1),
                    c(0, 1, 1),
                    c(1, 1, 0),
                    c(0, 1, 0))
    colnames(df) = c("Sequence", "position", "cat1", "cat1", "cat2", "cat2", "cat2")
    
    # rename column names to make them unique:
    newcols = c("Sequence", "position", paste0("c", 1:(ncol(df)-2)))
    oldcols = colnames(df)
    colnames(df) = newcols
    
    # make a crosswalk
    col_cross = tibble(oldcols = oldcols,
                       newcols = newcols)
    
    # gather the new columns, summarize across the old columns, spread
    df %>% 
      gather(key = "newcols", value = "val", -Sequence, -position) %>% 
      left_join(col_cross) %>% 
      group_by(Sequence, position, oldcols) %>% 
      summarize(n = sum(val)) %>% 
      spread(key = oldcols, value = n, fill = 0)
    

    【讨论】:

    • 您的脚本按原样工作,但将其与我自己的数据对比时,它会反刍原始表,但类别名称更改为样本名称更改为 c1、c2、c3 等。跨度>
    • 嗯,这还不足以让我进一步提供帮助。 col_cross 数据集是否适合您的数据? dplyr 语句中是否有任何消息?
    • 抱歉,一次做的事情太多。我相信这是因为我的数据已经有列名,但是您引用 colnames(df) 来保存旧的命名结构。我没有固定的列名结构,因为它会根据我正在查看的文件而变化。 (我一直在意外发帖 - 不熟悉在这里发帖。)我正在尝试以下操作:oldcols = colnames(df) newcols = c("locus", "strand", paste0("c", 1:(ncol( df)-2))) colnames(df) = newcols 运行大约需要 10 分钟,
    • 好的,我很确定我的方法会奏效。你可能想坐下来慢慢地用一个新的 R 会话来完成它。确保将我的方法中的对象名称更改为您加载数据的任何内容。最后我也没有提供赋值语句。祝你好运
    • 效果很好!就像你说的,我没有赋值语句,所以它输出垃圾。添加了一个作业,它使我需要的表。谢谢!!
    【解决方案2】:

    不一样的tidyverse 可能性:

    repair_names(df, prefix = "cat", sep = "_") %>% 
     rowid_to_column() %>%
     gather(var, val, -c(Sequence, position, rowid)) %>%
     mutate(temp = sub("\\_.*", "", var)) %>%
     arrange(rowid) %>%
     group_by(Sequence, position, temp) %>%
     summarise(res = sum(val),
               rowid = first(rowid)) %>%
     spread(temp, res) %>%
     select(-rowid)
    
      Sequence position  cat1  cat2
      <chr>    <chr>    <dbl> <dbl>
    1 abfsgdfy a           1.    1.
    2 abfsgdfy b           0.    3.
    3 dgdtecgd b           2.    1.
    

    首先,它将列名更改为具有"cat" 前缀和"_" 作为分隔符。其次,它将数据从宽格式转换为长格式。第三,使用sub("\\_.*", "", var) 它采用"_" 之前的字符串。然后,它对这些值求和。最后,它将数据返回为宽格式。

    使用@svenhalvorson 提供的样本数据:

    df <- tibble(c("abfsgdfy", "abfsgdfy", "dgdtecgd"),
                c("a", "b", "b"),
                c(0, 0, 1),
                c(1, 0, 1),
                c(0, 1, 1),
                c(1, 1, 0),
                c(0, 1, 0))
    colnames(df) <- c("Sequence", "position", "cat1", "cat1", "cat2", "cat2", "cat2")
    

    【讨论】:

    • 抱歉泛型,我实际上并没有使用 cat1、cat2 等。它可能是 Square、Turtle、Ball、Blue、55 等。但我可以制作一个翻译文件来分配它们通用 cat1、cat2 等并对此进行测试。 (我很有可能明天试试。)
    • 然后可以将第一行替换为repair_names(df, sep = "_")
    • 这也有效!谢谢!我必须对这两种解决方案进行计时,看看它们的比较情况。
    • 运行 Sven 的代码需要 3.94 分钟,运行你的代码需要 4.63 分钟。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 2018-12-04
    • 1970-01-01
    相关资源
    最近更新 更多