将长格式数据框转换为宽格式,但将列数保留在 R 中



我没有看到任何帖子解决我的问题。

我有一个两列数据框。具体来说,它有两个因素,分别为11985和20200水平。将两个因子的水平结合起来,总共给出849472个观测值。以下是数据框的示例:

Category    Gene
BP0000      Fp91000
BP0001      Fp82000
BP0002      Fp70000
BP0010      Fp72000
BP0021      Fp30000
BP0021      Fp30020 
BP0001      Fp30000
BP0000      Fp82000    

我想在一个原始类别中保留每个因子只重复一次,而在另一列中,我希望在同一单元格中与类别匹配的所有基因。这是我想要的格式:

Category    Gene
BP0000      Fp91000 Fp82000
BP0001      Fp82000 Fp30000
BP0002      Fp70000
BP0010      Fp72000
BP0021      Fp30000 Fp30020  

我已经尝试过匹配,但我只得到基因列的一个匹配项,并且有多个匹配项。很抱歉,如果这已经在其他问题中发布,但我没有看到这样的东西。

这是一个使用 dplyr 的解决方案

library(dplyr)
df <- data.frame(category = c("a", "a", "a", "b", "b", "b"),
value = c("c", "d", "e", "f", "g", "h"),
stringsAsFactors = FALSE)
df_out <- df %>%
group_by(category) %>%
mutate(value = paste(value, collapse=" ")) %>%
unique()

编辑:unique() 对于大型数据框来说非常慢。这效果要好得多。

df_out <- df %>%
group_by(category) %>%
mutate(value = paste(value, collapse=" ")) %>%
group_by(category, value) %>%
summarise()

df成为你的数据帧。 您可能想尝试:

getme<-function(x){
r<-paste(df[df$Category==x,]$Gene,collapse = " ")
return(r)
}
final<-data.frame(cbind(unique(as.character(df$Category)) ,unique(apply(df[1],1,getme))))
names(final)<-c("Category","Gene")

final是预期数据框。

要使用tidyrdplyrpurrr包扩展tidyverse选项,您可以将基因存储为每个类别的列表列。然后可以使用这进一步操作。

注意:我将基因和类别保存为字符而不是因子,这对于如此大的数据集似乎效率不高。

存储为列表列,为了方便起见,我添加了基因数量的计数:

library(tidyverse)
dataLC <- data %>% 
tidyr::nest(Gene, .key=GeneListCol) %>% 
mutate(n_genes = map_int(GeneListCol, ~max(row_number(.$Gene))))
# A tibble: 5 x 3
Category      GeneListCol n_genes
<chr>           <list>   <int>
1   BP0000 <tibble [2 x 1]>       2
2   BP0001 <tibble [2 x 1]>       2
3   BP0002 <tibble [1 x 1]>       1
4   BP0010 <tibble [1 x 1]>       1
5   BP0021 <tibble [2 x 1]>       2

这可以按原样使用purrr函数,并且在这种形式中可能是最有用的。

要将所选类别的基因提取为载体(这似乎是最有用的输出),您可以执行以下操作:

map(dataLC$GeneListCol, "Gene")[dataLC$Category=="BP0001"][[1]]
[1] "Fp82000" "Fp30000"

要获取包含所有基因的单个字符串(请注意,这不是真正的"宽格式"),请执行以下操作:

dataLC %>% 
mutate(geneList = map_chr(GeneListCol, ~paste(.$Gene, collapse =" "))) %>% 
select(-GeneListCol)
# A tibble: 5 x 3
Category n_genes        geneList
<chr>   <int>           <chr>
1   BP0000       2 Fp91000 Fp82000
2   BP0001       2 Fp82000 Fp30000
3   BP0002       1         Fp70000
4   BP0010       1         Fp72000
5   BP0021       2 Fp30000 Fp30020

了解列表列和使用purrr映射函数进行操作需要一段时间,但它可能非常有用。 请参阅 https://jennybc.github.io/purrr-tutorial/index.html 中的教程

最新更新