This is my first time working on a for-loop and I am fairly new to R. I'm having trouble running an ifelse()
function using the iteration counter of a for-loop. Below is data frame output from running the code posted at the bottom (looping only once), with a column manually added on the far right to explain the error in that row. Column concat_1
should simply be the concatenation of seqBase
and grpRank
when loop iteration i = 1:
> nCode
# A tibble: 8 x 6
Name Group nmCnt seqBase grpRnk concat_1 << ERROR in concat_1 column when loop i = 1
<chr> <dbl> <int> <int> <dbl> <dbl>
1 R 0 1 1 0 1
2 R 0 2 2 0 1 seqBase grpRank = 2
3 X 0 1 1 0 1
4 X 1 2 2 1 1.1 seqBase grpRank = 2.1
5 X 1 3 2 2 1.2 seqBase grpRank = 2.2
6 X 0 4 3 0 1 seqBase grpRank = 3
7 X 0 5 4 0 1 seqBase grpRank = 4
8 X 0 6 5 0 1 seqBase grpRank = 5
Why is the below ifelse()
(comment # to its right) producing incorrect results?
Code:
library(dplyr)
library(stringr)
myDF1 <-
data.frame(
Name = c("R","R","X","X","X","X","X","X"),
Group = c(0,0,0,1,1,0,0,0)
)
nCode <- myDF1 %>%
group_by(Name) %>%
mutate(nmCnt = row_number()) %>%
ungroup() %>%
mutate(seqBase = ifelse(Group == 0 | Group != lag(Group), nmCnt,0)) %>%
mutate(seqBase = na_if(seqBase, 0)) %>%
group_by(Name) %>%
fill(seqBase) %>%
mutate(seqBase = match(seqBase, unique(seqBase))) %>%
ungroup %>%
mutate(grpRnk = ifelse(Group > 0, sapply(1:n(), function(x) sum(Name[1:x]==Name[x] & Group[1:x] == Group[x])),0))
for(i in 1:1) {
concat_col <- str_c("concat_",i)
reSeq_col <- str_c("reSeq_",i)
nCode <- nCode %>%
mutate(!! concat_col:= as.numeric(paste0(ifelse(i==1,seqBase,reSeq_col),".",grpRnk))) # problem lies here
}
CodePudding user response:
There you go sir
myDF1 <-
data.frame(
Name = c("R","R","X","X","X","X","X","X"),
Group = c(0,0,0,1,1,0,0,0)
)
nCode <- myDF1 %>%
group_by(Name) %>%
mutate(nmCnt = row_number()) %>%
ungroup() %>%
mutate(seqBase = ifelse(Group == 0 | Group != lag(Group), nmCnt,0)) %>%
mutate(seqBase = na_if(seqBase, 0)) %>%
group_by(Name) %>%
fill(seqBase) %>%
mutate(seqBase = match(seqBase, unique(seqBase))) %>%
ungroup %>%
mutate(grpRnk = ifelse(Group > 0, sapply(1:n(), function(x) sum(Name[1:x]==Name[x] & Group[1:x] == Group[x])),0))
library(magrittr)
nCode %<>% mutate(
contact_col=as.numeric(
paste0(seqBase,".",grpRnk)
)
)
# %<>% is just a regular pipe with a fancy way to asign to variable (instead of `<-`)
CodePudding user response:
Below is a working example of code that resolves the issue. More complete explanations and example are at How to iteratively add to a data frame in R using a for-loop? and Unquote the variable name on the right side of mutate function in dplyr
library(dplyr)
library(rlang)
library(stringr)
myDF1 <-
data.frame(
Name = c("R","R","X","X","X","X","X","X","B","R","R","R","X","X","X"),
Group = c(0,0,0,1,1,0,0,0,0,0,2,2,3,3,3)
)
nCode <- myDF1 %>%
group_by(Name) %>%
mutate(nmCnt = row_number()) %>%
ungroup() %>%
mutate(seqBase = ifelse(Group == 0 | Group != lag(Group), nmCnt,0)) %>%
mutate(seqBase = na_if(seqBase, 0)) %>%
group_by(Name) %>%
fill(seqBase) %>%
mutate(seqBase = match(seqBase, unique(seqBase))) %>%
ungroup %>%
mutate(grpRnk = ifelse(Group > 0, sapply(1:n(), function(x) sum(Name[1:x]==Name[x] & Group[1:x] == Group[x])),0))
loopCntr <- nrow(unique(myDF1[myDF1$Group!=0,]))
for(i in 1:1) {
concat_curnt <- str_c("concat_",i)
concat_prior <- str_c("concat_",i-1)
nCode <- if(i==1){
nCode %>% mutate(!! concat_curnt:= as.numeric(paste0(seqBase,".",grpRnk)))} else {
nCode %>% mutate(!! concat_curnt:= as.numeric(paste0(!!rlang::sym(concat_prior),".",grpRnk)))
}
}
nCode