匹配2个不同数据帧之间的行值组合

时间:2016-10-21 20:05:11

标签: r loops dataframe pattern-matching

我有data.frame有16种不同的4种不同细胞标记组合

combinations_df

     FITC Cy3 TX_RED Cy5
 a    0   0      0   0
 b    1   0      0   0
 c    0   1      0   0
 d    1   1      0   0
 e    0   0      1   0
 f    1   0      1   0
 g    0   1      1   0
 h    1   1      1   0
 i    0   0      0   1
 j    1   0      0   1
 k    0   1      0   1
 l    1   1      0   1
 m    0   0      1   1
 n    1   0      1   1
 o    0   1      1   1
 p    1   1      1   1

我的“主”data.frame有10列和数千行。

> main_df
  a b FITC d Cy3 f TX_RED h Cy5 j
1 0 1    1 1   1 0      1 1   1 1
2 0 1    0 1   1 0      1 0   1 1
3 1 1    0 0   0 1      1 0   0 0
4 0 1    1 1   1 0      1 1   1 1
5 0 0    0 0   0 0      0 0   0 0
....

我想使用combinations_df中所有可能的16种组合来与main_df的每一行进行比较。然后,我想在第11列创建一个新的vector到更晚的cbindmain_df

示例输出

> phenotype
[1] "g" "i" "a" "p" "g" 

我考虑在for循环中执行while循环检查每行combinations_df行的每个main_df行。

听起来它可以工作,但我在main_df中接近1 000 000行,所以我想知道是否有人有更好的想法。

编辑:我忘了提及我只想将combinations_dfmain_df的第3,5,7,9列进行比较。它们具有相同的名称,但可能不那么明显。

编辑:Changin样本数据输出,因为不存在“t”

3 个答案:

答案 0 :(得分:2)

它不是很优雅,但这种方法效果很好。循环中没有循环,所以它应该运行得很好。可能尝试使用数据帧行进行匹配并一起取消循环,但这只是我能解决的最快方法。您可以查看包plyrdata.table。这类东西非常强大。

            main_text=NULL
            for(i in 1:length(main_df[,1])){
            main_text[i]<-paste(main_df[i,3],main_df[i,5],main_df[i,7],main_df[i,9],sep="")
            }
            comb_text=NULL
            for(i in 1:length(combinations_df[,1])){
            comb_text[i]<-paste(combinations_df[i,1],combinations_df[i,2],combinations_df[i,3],combinations_df[i,4],sep="")
            }

            rownames(combinations_df)[match(main_text,comb_text)]

答案 1 :(得分:2)

dplyr解决方案非常简单。首先,您需要将phenotype放在combinations_df中作为显式变量,如下所示:

#   phenotype FITC Cy3 TX_RED Cy5
#1          a    0   0      0   0
#2          b    1   0      0   0
#3          c    0   1      0   0
#4          d    1   1      0   0
# etc

dplyr允许您加入多个变量,因此从这里开始查找表型。

library(dplyr)
left_join(main_df, combinations_df, by=c("FITC", "Cy3", "TX_RED", "Cy5"))

#  a b FITC d Cy3 f TX_RED h Cy5 j phenotype
#1 0 1    1 1   1 0      1 1   1 1         p
#2 0 1    0 1   1 0      1 0   1 1         o
#3 1 1    0 0   0 1      1 0   0 0         e
#4 0 1    1 1   1 0      1 1   1 1         p
#5 0 0    0 0   0 0      0 0   0 0         a

我原本以为你必须用tidyr::unite连接列,但事实并非如此。

答案 2 :(得分:1)

这样的事情怎么样?我的结果与你的不同,因为combination_df中没有“t”。如果您愿意,可以在不指定新列的情况下执行此操作。这主要是为了说明目的。

combination_df <- read.table("Documents/comb.txt.txt", header=T)
main_df <- read.table("Documents/main.txt", header=T)

main_df
combination_df
main_df$key <- do.call(paste0, main_df[,c(3,5,7,9)])
combination_df$key <- do.call(paste0, combination_df)

rownames(combination_df)[match(main_df$key, combination_df$key)]