根据数据集属性将科分配给物种

问题描述 投票:0回答:2

我有一个包含数千行和以下列的数据集:ID、parentID、rank 和 ScientificName。

我希望创建一个新列,用于告知给定物种所属的familyrank中的级别)。如果有人可以提供帮助,将不胜感激。

示例数据:

ID = c('f1','f2','g1','g2','g3','g4','s1','s2','s3','s4','s5','s6') # all unique
parentID = c(NA,NA,'f1','f1','f2','f2','g1','g1','g2','g3','g3','g4')
rank = c('family','family','genus','genus','genus','genus','species','species','species','species','species','species')
scientificName = c('FamA','FamB','GenA','GenB','GenC','GenD','SpA','SpB','SpC','SpD','SpE','SpF')
dat = data.frame( ID, parentID, rank, scientificName)

我想要的输出(在本例中)将是一个额外的列,通知家庭如下: 家庭 = c('famA','famB','famA','famA','famB','famB','famA','famA','famA','famB','famB','famB ')

我考虑过创建家族及其 ID 的向量,然后通过家族名称更改 ParentID 列中的代码,然后尝试对属进行类似的操作,最终将家族信息与每个物种“链接”起来,但它有点混乱最后(也就是说,它没有成功)。我认为我需要的可以通过“dplyr”包来完成,但我被困住了......再次,我将不胜感激任何帮助。

r dplyr
2个回答
1
投票

这是一个很好的递归问题。这是一个矢量化的基本 R 解决方案。

find_family <- function(ID, parentID, scientificName) {
  find_family_id <- function(ID, parentID) {
    ID_new <- ifelse(!is.na(parentID), parentID, ID)
    parentID_new <- parentID[match(ID_new, ID)]
    if (all(is.na(parentID_new))) return(ID_new)
    find_family_id(ID_new, parentID_new)
  }
  family_ids <- find_family_id(ID, parentID)
  scientificName[match(family_ids, ID)]
}

dat$family <- with(dat, find_family(ID, parentID, scientificName))

dat
#    ID parentID    rank scientificName family
# 1  f1     <NA>  family           FamA   FamA
# 2  f2     <NA>  family           FamB   FamB
# 3  g1       f1   genus           GenA   FamA
# 4  g2       f1   genus           GenB   FamA
# 5  g3       f2   genus           GenC   FamB
# 6  g4       f2   genus           GenD   FamB
# 7  s1       g1 species            SpA   FamA
# 8  s2       g1 species            SpB   FamA
# 9  s3       g2 species            SpC   FamA
# 10 s4       g3 species            SpD   FamB
# 11 s5       g3 species            SpE   FamB
# 12 s6       g4 species            SpF   FamB

1
投票

您可以编写一个小型递归函数来查找 ID,直到达到家庭排名,然后使用一些迭代来应用此函数(此处

purrr::map_chr
以确保字符向量):

library(dplyr)
library(purrr)

get_family <- function(x) {
  i <- match(x, ID)
  with(dat, if (rank[i]=="family") scientificName[i] else get_family(parentID[i]))
}

dat |>
  mutate(family = map_chr(ID, get_family))

输出

   ID parentID    rank scientificName family
1  f1     <NA>  family           FamA   FamA
2  f2     <NA>  family           FamB   FamB
3  g1       f1   genus           GenA   FamA
4  g2       f1   genus           GenB   FamA
5  g3       f2   genus           GenC   FamB
6  g4       f2   genus           GenD   FamB
7  s1       g1 species            SpA   FamA
8  s2       g1 species            SpB   FamA
9  s3       g2 species            SpC   FamA
10 s4       g3 species            SpD   FamB
11 s5       g3 species            SpE   FamB
12 s6       g4 species            SpF   FamB
© www.soinside.com 2019 - 2024. All rights reserved.