我有两个相似数据框,列数相同但行数不同。两者之间的大多数条目是相同的,但在一些地方存在差异,这些是我关心的。两个数据框中的第一列用作密钥。
理想情况下,我希望能够看到它们是否已经改变,以及两个数据帧中的每一个的值。我的第一个解决方案是创建一个合并的数据框并按照这样的方式重新组织列:
df1<-data.frame(gene=c('cyp1a1','cyp2a6','srd5a','slc5a5','cox15'), updated=c(TRUE,TRUE,FALSE,TRUE,FALSE),version=c(2,3,1,2,1))
df2<-data.frame(gene=c('cyp1a1','cyp2a6','srd5a','slc5a5'), updated=c(FALSE,TRUE,FALSE,FALSE),version=c(1,2,1,1))
#merge data frames
comp<-merge(df1,df2, by="gene", all=TRUE)
#re-order columns side-by-side
#probably a better way to do this
ordList<-c(1,2,4,3,5)
comp<-comp[ordList]
所以现在我有一个并排的比较数据框。我不确定如何迭代数据帧来执行比较。最后我想创建一个新的数据框架,它使用比较中的信息来排除相同的数据(用空字符串替换),并包括不同于第一个df到第二个df的数据。
这就是comp现在的样子:
gene updated.x updated.y version.x version.y
1 cox15 FALSE NA 1 NA
2 cyp1a1 TRUE FALSE 2 1
3 cyp2a6 TRUE TRUE 3 2
4 slc5a5 TRUE FALSE 2 1
5 srd5a FALSE FALSE 1 1
这就是我想要的样子:
gene updated.x updated.y version.x version.y
1 cox15 FALSE NA 1 NA
2 cyp1a1 TRUE FALSE 2 1
3 cyp2a6 3 2
4 slc5a5 TRUE FALSE 2 1
5 srd5a
在我的实际数据中,每个数据框中有14列,数百行。我可能在将来进行类似的比较,因此有一个执行此任务的功能方式将是理想的。
答案 0 :(得分:2)
这是我的建议,考虑到你有14列:
library(data.table)
library(magrittr)
z = rbindlist(list(df1,df2), idcol=TRUE)
z[, lapply(.SD, . %>% unique %>% paste(collapse=";")), keyby=gene]
# gene .id updated version
# 1: cox15 1 FALSE 1
# 2: cyp1a1 1;2 TRUE;FALSE 2;1
# 3: cyp2a6 1;2 TRUE 3;2
# 4: slc5a5 1;2 TRUE;FALSE 2;1
# 5: srd5a 1;2 FALSE 1
这会显示每个基因出现在哪个数据框(.id
)以及属性(updated
和version
)。此显示自然延伸到其他表格,如list(df1,df2,df3)
。
如果您对未更改的值不感兴趣,可以使用if
测试隐藏它们:
z[, lapply(.SD, function(x)
if (uniqueN(x)>1) x %>% unique %>% paste(collapse=";")
else ""
), keyby=gene]
# gene .id updated version
# 1: cox15
# 2: cyp1a1 1;2 TRUE;FALSE 2;1
# 3: cyp2a6 1;2 3;2
# 4: slc5a5 1;2 TRUE;FALSE 2;1
# 5: srd5a 1;2
这也隐藏.id
基因只出现一次,但可以调整。
<强>解释即可。 z
包含所有数据,“堆叠”或以“长”格式存储。
要制作摘要表,我们使用z[, j, keyby=gene]
j
处理与每个.SD
组关联的数据子集keyby=gene
,并返回{{1}结果的列向量。
list
使用magrittr的一个功能。它只是. %>% unique %>% paste(collapse=";")
的易读版本。当它以function(y) paste(unique(y), collapse=";")
开头时,会将该函数应用于x
。如果您希望以标准方式编写它们,可以替换它。