R 多行中出现的匹配对
我在模拟一个雌雄鸟的种群,雌鸟选择一个配偶来繁殖。人口是一个数据框,每一行都是一个唯一的个体、其ID、其配偶的ID(如果配对)、其性别以及是否配对 我在跟踪谁和谁配对,这样我就可以跟踪后代以后会得到什么特征。数据框中包含雌性配对和雌性配对的数据,但我也希望在其中包含互惠关系(因此,selfID为d和E的行应分别包含mateID的A和B)。有没有一个简单的方法可以做到这一点?现在我什么都没想到R 多行中出现的匹配对,r,tidyverse,R,Tidyverse,我在模拟一个雌雄鸟的种群,雌鸟选择一个配偶来繁殖。人口是一个数据框,每一行都是一个唯一的个体、其ID、其配偶的ID(如果配对)、其性别以及是否配对 我在跟踪谁和谁配对,这样我就可以跟踪后代以后会得到什么特征。数据框中包含雌性配对和雌性配对的数据,但我也希望在其中包含互惠关系(因此,selfID为d和E的行应分别包含mateID的A和B)。有没有一个简单的方法可以做到这一点?现在我什么都没想到 df <- structure(list(selfID = c("A", "B", "C", "D
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
df以下是一种可能的方法:
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
for(i在df$mateID[!is.na(df$mateID)]){
df$mateID[df$selfID==i]解决方案,使用自身的合并
(不进行循环)
以下是两种都使用自连接的解决方案:
1.dplyr
这是一个稍微改进的版本,它使用left\u join()
代替merge()
,并使用coalesce()
代替基本R的ifelse()
:
selfID mateID性别配对
1:A D女性真实
2:BE女性真实
3:C女性假
4:D一个男性是真的吗
5:E B男性正确
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)
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
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