从数据框创建数据框

时间:2018-02-04 10:26:43

标签: r dataframe bioinformatics reshape create-table

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

    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

然后我想创建一个如下所示的数据帧(96 * 24-motifs *染色体 - ):

ID  foo  bar
1   100  1
2   50   1
3   75   1
4   200  1

3 个答案:

答案 0 :(得分:6)

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

我们添加一个列value来指示是否存在染色体,然后填写data.frame,确保每个motif-chromosome-Sample组合都有行,其中缺少的组合得到0 1}}在值列中。我们从主题和染色体列中创建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

答案 1 :(得分:3)

这似乎是一个典型的例子,当你想要使用factor并确保不丢弃空因子级别时(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个结果列上,结果如下所示:

enter image description here

答案 2 :(得分:1)

这对你有用。我使用了包tidyrdplyr。实际上,我倾向于使用unite中的expand.gridbase r来实现最终使用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