【问题标题】:Add a new column to data table向数据表添加新列
【发布时间】:2017-07-21 02:38:04
【问题描述】:

我正在处理一个包含 5 列的数据表:

gene_id, length, sample1_count, sample2_count, sample3_count

我想在现有表中添加 3 个新列,这些列代表样本 1、样本 2 和样本 3 的标准化计数(即将每个基因的每个样本计数除以计数总数)。

如何创建 3 个新列?或者我第一次在unix中生成文件时需要这样做吗?

【问题讨论】:

    标签: r


    【解决方案1】:

    我们可以使用data.table的方式来做到这一点

    library(data.table)
    nm1 <- grep("^sample\\d+_count", names(df1), value = TRUE)
    setDT(df1)[, paste0("Norm_", nm1) := lapply(.SD, `/`, .N), gene_id, .SDcols = nm1]
    

    如果是除以sum

    setDT(df1)[, paste0("Norm_", nm1) := lapply(.SD, function(x) x/sum(x)), 
                                 gene_id, .SDcols = nm1]
    

    【讨论】:

      【解决方案2】:

      包含一个最小可重现示例可能会有所帮助,但以下将调用一个函数,用于将字段除以 mtcars 数据集中的柱面数,并将输出存储在新变量名下:

      mtcars
      fields_input <- c('hp', 'disp')
      fields_output <- c('hp_per_cyl', 'disp_per_cyl')
      divide_by_cyl <- function(v) v / mtcars[['cyl']]
      mtcars[fields_output] <- lapply(mtcars[fields_input], divide_by_cyl)
      mtcars
      

      【讨论】:

        【解决方案3】:

        在我看来,您的数据可以使用长格式更好地表示。使用长格式并使用data.table,您的问题会变得更加简单:

        # Some sample data
        dt <- data.table(
                 gene_id = sample(LETTERS, 10),
                 length = sample(1:25, 10),
                 sample1 = sample(1:1000, 10),
                 sample2 = sample(1:1000, 10),
                 sample3 = sample(1:1000, 10))
        
        # Convert to long format
        dt_long = melt(dt, id.vars = c("gene_id", "length"), value.name = "count")
        
        # Calculate your normalized counts for each gene_id / length combination
        dt_long[, normalized_count := count / sum(count), by = c("gene_id", "length")]
        

        如果您再次需要宽格式输出,您可以随时使用:

        dcast(dt_long, gene_id + length ~ variable)
        

        得到:

        gene_id length   sample1    sample2    sample3
         1:       B     16 0.2666667 0.05232068 0.68101266
         2:       C      6 0.7737226 0.01459854 0.21167883
         3:       J      3 0.4131455 0.41549296 0.17136150
         4:       P     13 0.4846847 0.44054054 0.07477477
         5:       Q     23 0.3425573 0.11545802 0.54198473
         6:       R     12 0.6018576 0.21114551 0.18699690
         7:       S      4 0.5416924 0.30759728 0.15071032
         8:       T     24 0.1838666 0.40694006 0.40919333
         9:       X     11 0.4468085 0.45319149 0.10000000
        10:       Z     20 0.2267706 0.43144899 0.34178038
        

        【讨论】:

          【解决方案4】:

          这是一些可重复的数据:

           set.seed(1)
           df <- data.frame(gene_id = 1:5, 
                            length = sample(1:100, 5), 
                            sample1_count = sample(1:10, 5), 
                            sample2_count = sample(1:10, 5), 
                            sample3_count = sample(1:10, 5))
          

          这是如何通过样本计数进行归一化、重命名归一化列并最终将归一化列连接到原始数据框(使用基本 R 函数):

          norms <- sapply(df[ c("sample1_count", "sample2_count", "sample3_count")], function(x) x/sum(x))
          colnames(norms) <- sub("count", "norm", colnames(norms))
          df2 <- cbind(df, norms)
          

          以下是标准化计数:

          df2[, c("gene_id", "length", "sample1_norm", "sample2_norm", "sample3_norm")]
            gene_id length sample1_norm sample2_norm sample3_norm
          1       1     27   0.29032258   0.11538462   0.15151515
          2       2     37   0.32258065   0.07692308   0.21212121
          3       3     57   0.19354839   0.23076923   0.24242424
          4       4     89   0.16129032   0.38461538   0.09090909
          5       5     20   0.03225806   0.19230769   0.30303030
          

          【讨论】:

            猜你喜欢
            • 2021-01-23
            • 1970-01-01
            • 2018-05-17
            • 2012-12-29
            • 2018-10-09
            • 2011-08-14
            • 1970-01-01
            • 2013-10-05
            • 1970-01-01
            相关资源
            最近更新 更多