Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 多行中出现的匹配对_R_Tidyverse - Fatal编程技术网

R 多行中出现的匹配对

R 多行中出现的匹配对,r,tidyverse,R,Tidyverse,我在模拟一个雌雄鸟的种群,雌鸟选择一个配偶来繁殖。人口是一个数据框,每一行都是一个唯一的个体、其ID、其配偶的ID(如果配对)、其性别以及是否配对 我在跟踪谁和谁配对,这样我就可以跟踪后代以后会得到什么特征。数据框中包含雌性配对和雌性配对的数据,但我也希望在其中包含互惠关系(因此,selfID为d和E的行应分别包含mateID的A和B)。有没有一个简单的方法可以做到这一点?现在我什么都没想到 df <- structure(list(selfID = c("A", "B", "C", "D

我在模拟一个雌雄鸟的种群,雌鸟选择一个配偶来繁殖。人口是一个数据框,每一行都是一个唯一的个体、其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 

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