【问题标题】:Create a dataframe from a dataframe从数据框创建数据框
【发布时间】:2018-07-14 09:29:37
【问题描述】:

我想从之前创建的数据框创建一个数据框。我的第一个数据框是:

    Sample motif chromosome
    1      CT-G.A    1
    1      TA-C.C    1
    1      TC-G.C    2
    2      CG-A.T    2
    2      CA-G.T    2

然后我想为所有 (96*24-motifs*chromosomes-) 创建一个如下所示的数据框:

    Sample CT-G.A,chr1 TA-C.C,chr1 TC-G.C,chr1 CG-A.T,ch1 CA-G.T,ch1 CT-G.A,chr2 TA-C.C,chr2 TC-G.C,chr2 CG-A.T,ch2 CA-G.T,ch2 
    1       1             1           0           0            0        0          0     1    0     0      0      0
    2       0             0           0           0            0        0          0     0    0     0      1      1

【问题讨论】:

    标签: r dataframe bioinformatics reshape create-table


    【解决方案1】:

    这是使用dplyrtidyr 的可能解决方案。

    我们添加一列 value 以指示是否存在染色体,然后完成 data.frame,确保每个 motif-chromosome-Sample 组合都有行,其中缺少的组合在值列中得到 0。我们从主题和染色体列中创建一个key,然后丢弃这些列。最后,我们将data.frame 从长改成宽(参见here)以获得您想要的格式。希望这会有所帮助!


    df = read.table(text="Sample motif chromosome
    1      CT-G.A    1
                    1      TA-C.C    1
                    1      TC-G.C    2
                    2      CG-A.T    2
                    2      CA-G.T    2
                    2      CA-G.T    2",header=T)
    
    
    library(tidyr)
    library(dplyr)
    
    df  %>% mutate(value=1) %>% complete(motif,chromosome,Sample,fill=list(value=0)) %>%
      mutate(key=paste0(motif,',chr',chromosome)) %>%
      group_by(Sample,key) %>%
      summarize(value = sum(value)) %>%
      spread(key,value) %>% 
      as.data.frame
    

    输出:

      Sample CA-G.T,chr1 CA-G.T,chr2 CG-A.T,chr1 CG-A.T,chr2 CT-G.A,chr1 CT-G.A,chr2 TA-C.C,chr1 TA-C.C,chr2 TC-G.C,chr1 TC-G.C,chr2
    1      1           0           0           0           0           1           0           1           0           0           1
    2      2           0           2           0           1           0           0           0           0           0           0
    

    【讨论】:

    • 我在我的数据框上使用了它,但它给出了这个错误:“错误:行标识符重复”
    • 您的数据中可能存在重复项。我在您的数据中添加了一个重复行,并扩展了代码来处理这些数据。希望能解决。
    【解决方案2】:

    这似乎是您想要使用 factors 并确保不删除空因子水平的经典案例(除非明确告知不要这样做,否则 dcast 和其他函数可能会这样做)。

    使用@Florian's sample data,可以试试:

    library(data.table)
    cols <- c("motif", "chromosome")
    setDT(df)[, (cols) := lapply(.SD, factor), .SDcols = cols][
      , dcast(unique(.SD)[, value := 1L], 
              Sample ~ motif + chromosome, value.var = "value", 
              fill = 0L, drop = FALSE)]
    #   Sample CA-G.T_1 CA-G.T_2 CG-A.T_1 CG-A.T_2 CT-G.A_1 CT-G.A_2 TA-C.C_1 TA-C.C_2 TC-G.C_1 TC-G.C_2
    # 1      1        0        0        0        0        1        0        1        0        0        1
    # 2      2        0        1        0        1        0        0        0        0        0        0
    

    我已将“cols”和myfun() 移到转换之外,以节省一些输入并使事情看起来更整洁。


    使用“tidyverse”,我会采取与@Florian 略有不同的方法,可能类似于:

    library(tidyverse)
    df %>%
      mutate_at(c("motif", "chromosome"), factor) %>%
      mutate(value = 1) %>%
      distinct() %>%
      mutate(key = interaction(motif, chromosome)) %>%
      select(-motif, -chromosome) %>%
      spread(key, value, fill = 0, drop = FALSE)
    

    基准

    这些方法和@Florian 的基准可以在at this Gist 找到。

    在 10,000 行和 20 个结果列上,结果如下所示:

    【讨论】:

      【解决方案3】:

      这对你有用。我使用了包tidyrdplyr。实际上,我更喜欢使用base r中的uniteexpand.grid来实现最终使用spread

      df <- read.table(text = "Sample motif chromosome
          1      CT-G.A    1
                 1      TA-C.C    1
                 1      TC-G.C    2
                 2      CG-A.T    2
                 2      CA-G.T    2", header = TRUE)
      
      #add a column to represent presence of chromosome    
      df$val <- 1
      library(tidyr)
      library(dplyr)
      
      #Complete missing rows
      df_complete <- left_join(
                expand.grid(Sample=unique(df$Sample), motif=unique(df$motif), 
                               chromosome=unique(df$chromosome)),
                   df, by = c("Sample", "motif", "chromosome"), copy = TRUE)
      
      #Additional rows should have val = 0
      df_complete$val[is.na(df_complete$val)] <- 0
      
      df_complete %>%
          unite(motif, c("motif", "chromosome"), sep = ",chr" ) %>% 
          spread(motif, val)
      
      #Result
        Sample CA-G.T,chr1 CA-G.T,chr2 CG-A.T,chr1 CG-A.T,chr2 CT-G.A,chr1 CT-G.A,chr2 TA-C.C,chr1 TA-C.C,chr2 TC-G.C,chr1 TC-G.C,chr2
      1      1           0           0           0           0           1           0           1           0           0           1
      2      2           0           1           0           1           0           0           0           0           0           0
      

      【讨论】:

        猜你喜欢
        • 2020-02-26
        • 1970-01-01
        • 1970-01-01
        • 2022-07-31
        • 2021-09-08
        • 2019-05-27
        • 2021-12-22
        • 2016-10-14
        相关资源
        最近更新 更多