我正在模拟雄性和雌性鸟类的种群,雌性选择与之交配的伴侣。人口是一个数据框,每一行都是一个唯一的个体,其ID,其伴侣的ID(如果已配对),性别以及是否已配对。
我正在跟踪谁与谁配对,因此我可以跟踪后代将获得哪些特征。雌雄配对的数据以及在数据框中与谁配对的数据,但是我也想在其中具有相互关系(因此,selfID为D和E的行应分别具有mateID的A和B)。有没有简单的方法可以做到这一点?现在什么都没想到...
df <- structure(list(selfID = c("A", "B", "C", "D", "E"), mateID = c("D",
"E", NA, NA, NA), sex = c("female", "female", "female", "male",
"male"), paired = c(TRUE, TRUE, FALSE, NA, NA)), row.names = c(NA,
-5L), class = c("tbl_df", "tbl", "data.frame"))
selfID mateID sex paired
<chr> <chr> <chr> <lgl>
1 A D female TRUE
2 B E female TRUE
3 C NA female FALSE
4 D NA male NA
5 E NA male NA
答案 0 :(得分:1)
这是一种可能的方法:
for(i in df$mateID[!is.na(df$mateID)]) {
df$mateID[df$selfID == i] <- df$selfID[df$mateID == i & !is.na(df$mateID)]
}
df$paired[!is.na(df$mateID)] <- T
df
# # A tibble: 5 x 4
# selfID mateID sex paired
# <chr> <chr> <chr> <lgl>
# 1 A D female TRUE
# 2 B E female TRUE
# 3 C <NA> female FALSE
# 4 D A male TRUE
# 5 E B male TRUE
答案 1 :(得分:1)
本身使用merge
的解决方案(不执行循环)。
library(dplyr)
merge(df, df, by.x = "selfID", by.y = "mateID", all.x = TRUE) %>%
mutate(mateID = ifelse(is.na(mateID), selfID.y, mateID),
paired = ifelse(is.na(paired.x), paired.y, paired.x)) %>%
select(selfID, sex = sex.x, mateID, paired)
答案 2 :(得分:1)
以下是两个都使用 self join 的解决方案:
这是PoGibas' answer的某种修饰版本,它使用left_join()
代替merge()
和coalesce()
代替基数R的ifelse()
:
library(dplyr)
df %>%
left_join(df, by = c("selfID" = "mateID")) %>%
mutate(mateID = coalesce(mateID, selfID.y),
paired = coalesce(paired.x, paired.y)) %>%
select(selfID, mateID, sex = sex.x, paired)
# A tibble: 5 x 4 selfID mateID sex paired <chr> <chr> <chr> <lgl> 1 A D female TRUE 2 B E female TRUE 3 C NA female FALSE 4 D A male TRUE 5 E B male TRUE
为完整起见(并注意问题已用tidyverse标记),这是一个单行代码,它使用data.table
的能力自我执行更新加入:
library(data.table)
setDT(df)[df, on = .(selfID = mateID), `:=`(mateID = i.selfID, paired = TRUE)]
df
selfID mateID sex paired 1: A D female TRUE 2: B E female TRUE 3: C <NA> female FALSE 4: D A male TRUE 5: E B male TRUE