将频率数据帧转换为更宽的格式

时间:2017-11-11 08:07:40

标签: r dataframe dplyr tidyverse

我的数据框看起来像这样。

input dataframe

position,mean_freq,reference,alternative,sample_id
1,0.002,A,C,name1
2,0.04,G,T,name1
3,0.03,A,C,name2

这些数据是假设基因组中给定位置的核苷酸差异,mean_freq是相对于参考的,因此第一行表示C's的比例0.002暗示{ {1}}位于A

我希望通过创建新列来将其转换为不同的结构,

0.998

我尝试过这种方法

desired_output

position,G,C,T,A,sampleid
1,0,0.002,0,0.998,name1
2, 0.96,0,0.04,0,name
3,0,0.93,0,0.07,name2

我遇到了错误

per_position_full_nt_freq <- function(x){
  df <- data.frame(A=0, C=0, G=0, T=0)
  idx <- names(df) %in% x$alternative
  df[,idx] <- x$mean_freq
  idx2 <- names(df) %in% x$reference 
  df[,idx2] <- 1 - x$mean_freq
  df$position <- x$position
  df$sampleName <- x$sampleName
  return(df)
}

desired_output_dataframe <- per_position_full_nt_freq(input_dataframe)

另外,我觉得必须有一个更直观的解决方案,并且可能使用In matrix(value, n, p) : data length [8905] is not a sub-multiple or multiple of the number of columns tidyr。 如何方便地将输入数据帧转换为所需的输出数据帧格式?

谢谢。

2 个答案:

答案 0 :(得分:4)

一种选择是使用&#39; G&#39;&#39; C&#39;&#39; T&#39;创建matrix 0, &#39; A&#39;列名称match包含原始数据集的列名称,使用row/column索引分配值,然后cbind使用原始数据集&#39; s&#39;位置&# 39;和&#39; sample_id&#39;,列

m1 <- matrix(0, ncol=4, nrow=nrow(df1), dimnames = list(NULL, c("G", "C", "T", "A")))
m1[cbind(seq_len(nrow(df1)), match(df1$alternative, colnames(m1)))]  <-  df1$mean_freq
m1[cbind(seq_len(nrow(df1)), match(df1$reference, colnames(m1)))]  <-  0.1 - df1$mean_freq
cbind(df1['position'], m1, df1['sample_id'])
#   position    G     C    T     A sample_id
#1        1 0.00 0.002 0.00 0.098     name1
#2        2 0.06 0.000 0.04 0.000     name1
#3        3 0.00 0.030 0.00 0.070     name2

答案 1 :(得分:0)

以下应该可以解决问题:

library(readr)
library(dplyr)
library(tidyr)

input_df <- read_csv(
  'position,mean_freq,reference,alternative,sample_id
  1,0.002,A,C,name1
  2,0.04,G,T,name1
  3,0.03,A,C,name2'
)

input_df %>%
  mutate( ref_val = 0.1 -mean_freq) %>%
  spread(alternative, mean_freq, fill=0) %>%
  spread(reference, ref_val, fill=0) %>%
  select( position, G, C, T, A, sample_id )

您在这里有一个假设是替代和引用是不同的,否则您将得到两个具有相同名称但不同值的列。如果需要,您需要在代码的开头用几个命令来处理。