I'm trying to join two data frames, nCode and index, as shown in the below image. The code shown at the bottom adds the concat column from index to nCode by matching the eleCnt column, but I am trying to add the condition that concat is only added (joined) if the condition is met that Group <> 0 or the grpID between the two data frames match. Is there a clean, easy way to do this in dplyr or base R? I'm avoiding data.table for now as I'm newish to R and prefer keeping it simpler for now. I've been fooling around with dplyr's filter() function to add this condition but no luck yet.
This type of question is addressed in other posts like dplyr left_join by less than, greater than condition, and I like Jon Spring's solution to use the development version of left_join() where you could use left_join(x, y, join_by(a >= b, c < d)) for example, but I am wary of using a dev version for fear of bugs etc.
Code:
library(dplyr)
myDF5 <-
data.frame(
Name = c("B","R","R","R","B","X","X"),
Group = c(0,0,1,1,0,2,2)
)
nCode <- myDF5 %>%
mutate(origOrder = row_number()) %>%
group_by(Name) %>%
mutate(eleCnt = row_number()) %>%
ungroup() %>%
mutate(seqBase = ifelse(Group == 0 | Group != lag(Group), eleCnt,0)) %>%
mutate(seqBase = na_if(seqBase, 0)) %>%
group_by(Name) %>%
fill(seqBase) %>%
mutate(seqBase = match(seqBase, unique(seqBase))) %>%
ungroup()
grpRnk <- nCode %>% select(Name,Group,eleCnt) %>%
filter(Group > 0) %>%
group_by(Name,Group) %>%
slice(which.min(Group)) %>%
ungroup() %>%
arrange(eleCnt) %>%
mutate(grpRnk = dense_rank(eleCnt)) %>%
select(-eleCnt)
nCode <- left_join(nCode,grpRnk, by = c("Name", "Group")) %>%
mutate(subGrp = ifelse(Group > 0,
sapply(1:n(), function(x) sum(Name[1:x]==Name[x]&
Group[1:x] == Group[x])), 0)) %>%
mutate(grpID = sapply(1:n(), function(x) sum(eleCnt[(Group[1:n()] == Group[x]) &
(Name[1:n()] == Name[x]) &
(Group[1:n()]!= 0)])))
i = 1
index <-
filter(nCode, grpRnk == i) %>%
distinct(eleCnt, .keep_all = TRUE) %>%
mutate(grpID = sapply(1:n(), function(x) sum(eleCnt))) %>%
mutate(concat = seqBase + subGrp/10) %>%
select(eleCnt,grpID,concat)
index %>%
select(eleCnt,concat) %>%
left_join(nCode, ., by = "eleCnt")
