从数据框创建数据框

Create a dataframe from a dataframe

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

    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

这是使用 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

这对你有用。我使用了包 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

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

使用,你可以试试:

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 个结果列中,结果如下: