【问题标题】:Matching two columns in dataframe to multiple columns in another dataframe returning first matching column将数据框中的两列与另一个数据框中的多列相匹配,返回第一个匹配列
【发布时间】:2018-06-25 20:11:49
【问题描述】:

我正在尝试将数据帧中的两列与另一个数据帧匹配,并且我希望返回的值是第二个数据帧中首先匹配两个初始列的值。

例如: 我想采用以下数据框:

Fasta<-c("X1","X1","X2","X2","X3","X3")
Species<-c("Kiwi","Chicken","Weta","Cricket","Tuatara","Gecko")
testdata<-as.data.frame(cbind(Fasta,Species))
testdata<-aggregate(Species ~ Fasta, testdata, I)
testdata<-aggregate(Species ~ Fasta, testdata, I)

Fasta    Species1 Species2

X1       Kiwi      Chicken
X2       Weta      Cricket
X3       Tuatara   Gecko

以下是我的第二个数据框

Species<-c("Kiwi","Chicken","Weta","Cricket","Frog","Gecko")
Genus<-c("Orn","Norn","Genus2","Genus2","Spec","NoSpec")
Order<-c("Bird","Bird","Order2","Order2","Norder","Geckn")
Kingdom<-rep("Animal",each=6)
lookup<-data.frame(cbind(Species,Genus,Order,Kingdom))

Species Genus   Order   Kingdom

Kiwi    Orn     Bird    Animal
Chicken Norn    Bird    Animal
Weta    Genus2  Order2  Animal
Cricket Genus2  Order2  Animal
Frog    Spec    Norder  Animal
Gecko   NoSpec  Geckn   Animal

我想在第二个数据框中找到匹配 Species1 和 Species2 的第一列并返回其名称。理想情况下,这会给我以下输出:

Fasta   Species1    Species2    MatchLevel

X1      Kiwi        Chicken     Order
X2      Weta        Cricket     Genus
X3      Tuatara     Gecko       Kingdom

对不同格式的数据开放,

【问题讨论】:

  • testdata$MatchLevel &lt;- mapply(function(s1, s2){names(lookup)[which(unlist(lookup[s1 == lookup$Species, ]) == unlist(lookup[s2 == lookup$Species, ]))[1]]}, testdata$Species1, testdata$Species2),虽然我怀疑还有更优雅的选择

标签: r statistics bioinformatics


【解决方案1】:

此函数利用了分类群的嵌套性(即,如果两个物种属于同一属,则它们必须处于相同的顺序等)。同一属中的两个物种得到 3 分,因为所有 3 个分类级别都匹配,如果在相同的顺序中,则为 2,如果在同一个界中,则为 1。也不可能匹配。

match2species <- function(a, b, lookup_table = lookup) {
  sp_a <- lookup_table[lookup_table$Species == a, ]
  sp_b <- lookup_table[lookup_table$Species == b, ]

  matches <- sum(sp_a[-1] == sp_b[-1])
  ifelse(matches > 0, c('Kingdom','Order','Genus')[matches], 'No match')

}

可以为数据框中的任何一对物种调用该函数。

> match2species('Chicken','Kiwi')
[1] "Order"
> match2species('Weta','Cricket')
[1] "Genus"
> match2species('Frog','Gecko')
[1] "Kingdom"

【讨论】:

  • 这真的很有帮助,我面临的唯一问题是我不能将它应用于多个列,例如:match2species(testdata$V1,testdata$V2) 当我这样做时,我得到以下错误:Ops.factor(lookup_table$Species, a) 中的错误:因子的水平集不同
  • 你需要data.frames有因子吗?如果它们是字符可能会有所帮助(在调用 as.data.frame() 和 data.frame() 时设置 stringsAsFactors = FALSE)。然后就可以使用dplyr的rowwise和mutate来申请每一行testdata:testdata %>% rowwise() %>% mutate(Match = match2species(V1, V2))
  • @user2738526 的解决方案将起作用,但您也可以使用 base R 将函数应用于所有列:apply(testdata, 1, function(row) match2species(row['V1'], row['V2']))(您的查找表中应该包含 Tuatara 而不是 Frog)跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-11
  • 1970-01-01
  • 2021-04-19
  • 2019-01-20
相关资源
最近更新 更多