我有一个数据框,其中显示了一些有关个人(ID
)的数据,他们生活的每一年都有一行。它还包含有关父母ID(P.ID
)和出生时父母年龄(P.AB
)的信息。
# Dataframe A: 1 row per individual
dfA <- data.frame(
"ID" = c("A", "B", "C", "D", "E"),
"P.ID" = c(NA, "A", "A", "B", "B"),
"P.AB" = c(NA, 3, 4, 2, 4),
"LS" = c(5, 6, 3, 4, 5))
# Dataframe B: 1 row per year of life
dfB <- data.frame("ID" = rep(dfA[,'ID'], dfA[,'LS']+1))
dfB <- merge(dfB, dfA, by = "ID")
dfB[ ,'AGE'] <- 0
for(i in 2:length(dfB[,1])){
if(dfB[i,'ID'] == dfB[i-1, 'ID']){
dfB[i,'AGE'] <- dfB[i-1, 'AGE'] + 1
}
}
给予:
> head(dfB)
ID P.ID P.AB LS AGE
1 A <NA> NA 5 0
2 A <NA> NA 5 1
3 A <NA> NA 5 2
4 A <NA> NA 5 3
5 A <NA> NA 5 4
6 A <NA> NA 5 5
然后我想做的就是让R在REP
列中加一个“ 1”,以显示某人复制的年份。例如。当 A 为3时, B 出生于 A ,因此 A 3岁的那一行获得1我一直在尝试使用%in%
来做到这一点,但是努力使它符合多个条件。一种解决方法是将ID
和age
粘贴在一起(再加上一个随机字符串以确保在我的较大数据集中没有虚假重复),但是这似乎缺乏高雅感,并且不必要复杂。我想知道一个人可以/如何将%in%
用于多个条件?
# Add 1 where an individual reproduced
dfB[,'REP'] <- 0
dfB[,'T1'] <- paste0(dfB[,'AGE'], "abcdefghijk656hjhjhj", dfB[,'ID'])
dfB[,'T2'] <- paste0(dfB[,'P.AB'], "abcdefghijk656hjhjhj", dfB[,'P.ID'])
dfB[,'REP'][dfB[,'T1'] %in% dfB[,'T2']] <- 1
dfB[,'T2'] <- dfB[,'T1'] <- NULL
dfB
输出将如下所示:
> dfB
ID P.ID P.AB LS AGE REP
1 A <NA> NA 5 0 0
2 A <NA> NA 5 1 0
3 A <NA> NA 5 2 0
4 A <NA> NA 5 3 1
5 A <NA> NA 5 4 1
6 A <NA> NA 5 5 0
7 B A 3 6 0 0
8 B A 3 6 1 0
9 B A 3 6 2 1
10 B A 3 6 3 0
11 B A 3 6 4 1
12 B A 3 6 5 0
13 B A 3 6 6 0
14 C A 4 3 0 0
15 C A 4 3 1 0
16 C A 4 3 2 0
17 C A 4 3 3 0
18 D B 2 4 0 0
19 D B 2 4 1 0
20 D B 2 4 2 0
21 D B 2 4 3 0
22 D B 2 4 4 0
23 E B 4 5 0 0
24 E B 4 5 1 0
25 E B 4 5 2 0
26 E B 4 5 3 0
27 E B 4 5 4 0
28 E B 4 5 5 0
我尝试了这个(以及其中的一些变体),它很接近,可以将它们正确地添加到合适的个人,但是在错误的年份-看到 A 和 B 都可以复制,并且复制发生在2、3和4岁(总共6个事件),但是 A 和 B 都没有复制到4岁,而< em> A 也在3岁时复制, B 也在2岁时复制(总共4个事件):
dfB[,'REP'][dfB[,'P.ID'] %in% dfB[,'ID'] & dfB[,'P.AB'] %in% dfB[,'AGE']] <- 1
dfB[,'REP'][dfB[,'ID'] %in% dfB[,'P.ID'] & dfB[,'AGE'] %in% dfB[,'P.AB'] ] <- 1
作为对此的扩展,我希望每个年龄段的后代数量而不是1或0,这是可行的(我更改了dfA
,所以 B 和 C 是双胞胎),但效率可能也很低:
# Counts of offspring per year
dfA[,'PASTED'] <- paste0(dfA[,'P.ID'], "randomtext", dfA[,'P.AB'])
# Create rep column
dfB[,'REP'] <- 0
# Paste together ID and AGE columns to give unique row identifiers
dfB[,'T1'] <- paste0(dfB[,'AGE'], "randomtext", dfB[,'ID'])
dfB[,'T2'] <- paste0(dfB[,'P.AB'], "randomtext", dfB[,'P.ID'])
# Add Reps
dfB[,'REP'][dfB[,'T1'] %in% dfB[,'T2']] <- table(dfA[,'PASTED'])
# Remove excess columns
dfB[,'T2'] <- dfB[,'T1'] <- NULL
答案 0 :(得分:0)
如果您正在考虑将%in%
用于多列,那么您可能正在寻找合并/联接。您可以使用基数R来完成所有操作,但是我发现使用dplyr
library(dplyr)
dfB %>%
select(P.ID, P.AB) %>%
distinct() %>%
filter(!is.na(P.ID)) %>%
rename(ID=P.ID, AGE=P.AB) %>%
mutate(REP=1) %>%
left_join(dfB, .) %>%
mutate(REP=coalesce(REP, 0))
基本上,您只是从数据中找到唯一的父/年龄值,然后将其重新连接到相同的data.frame,但在不同的列上匹配。