简体   繁体   中英

How to append dataframe column names with for-loop iteration count in R?

This is my first-time trying a for-loop in R. I am trying to append to the looped-over data frame column header names, the loop iteration count as shown below in the image. Columns concat , alloc , merge , reSeq , are generated in the loop and I'd like to change their names to concat_1, alloc_1, merge_1, reSeq_1 for the first loop, etc. Any recommendations for how to do this?

在此处输入图像描述

I'm starting very easy, looping only 1 time so I can gently step into this. In my next step I'll expand the loop so that columns are added to the right and similarly sequentially renamed. I did attempt to append to column names in the first mutate under the for-loop in the below code for each reference to concat but it doesn't work: mutate(paste0("concat_",i) = as.numeric... So I imagine the solution will be something like running colnames(...) at the bottom of the loop, etc.

Here's the code with example DF:

library(dplyr)

myDF1 <- data.frame(
    Name = c("R","R","B","R","X","X"),
    Group = c(0,0,0,0,1,1))

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) {nCode <- nCode %>% 
    mutate(concat = as.numeric(paste0(seqBase,".",grpRnk)))
    
    index <- filter(nCode, Group !=0) %>% 
      select(concat) %>% 
      distinct() %>% 
      mutate(truncInd = trunc(concat)) %>%
      group_by(truncInd) %>% 
      mutate(cumGrp = cur_group_id()) %>%
      ungroup() %>%
      select(-truncInd)
    index <- if(ifelse(loopCntr > 0, min(index$concat), Inf) >= 2){
      rbind(data.frame(concat=c(1),cumGrp=c(1)),index)}else{index}
    
    nCode <- nCode %>%
      mutate(alloc = index$concat[index$cumGrp==1][nmCnt]) %>%
      mutate(merge = ifelse(is.na(alloc),seqBase,alloc)) %>%
      group_by(Name) %>%
      mutate(reSeq = match(trunc(merge), unique(trunc(merge)))) %>%
      mutate(reSeq = (reSeq + round(merge%%1 * 10,0)/10)) %>%
      ungroup()
  } # end for-loop
      
  print.data.frame(nCode)

Perhaps, assign with names<- or setNames or use rename_with at the end of the loop

library(dplyr)
library(stringr)
for(i in 1:1) {nCode <- nCode %>% 
    mutate(concat = as.numeric(paste0(seqBase,".",grpRnk)))
    
    index <- filter(nCode, Group !=0) %>% 
      select(concat) %>% 
      distinct() %>% 
      mutate(truncInd = trunc(concat)) %>%
      group_by(truncInd) %>% 
      mutate(cumGrp = cur_group_id()) %>%
      ungroup() %>%
      select(-truncInd)
    index <- if(ifelse(loopCntr > 0, min(index$concat), Inf) >= 2){
      rbind(data.frame(concat=c(1),cumGrp=c(1)),index)}else{index}
    
    nCode <- nCode %>%
      mutate(alloc = index$concat[index$cumGrp==1][nmCnt]) %>%
      mutate(merge = ifelse(is.na(alloc),seqBase,alloc)) %>%
      group_by(Name) %>%
      mutate(reSeq = match(trunc(merge), unique(trunc(merge)))) %>%
      mutate(reSeq = (reSeq + round(merge%%1 * 10,0)/10)) %>%
      ungroup()
     nCode <- nCode %>%
        rename_with(~ str_c(.x, "_", i), c("concat", "alloc", "merge", "reSeq"))
  } # end for-loop

-output

> nCode
# A tibble: 6 × 9
  Name  Group nmCnt seqBase grpRnk concat_1 alloc_1 merge_1 reSeq_1
  <chr> <dbl> <int>   <int>  <dbl>    <dbl>   <dbl>   <dbl>   <dbl>
1 R         0     1       1      0      1       1.1     1.1     1.1
2 R         0     2       2      0      2       1.2     1.2     1.2
3 B         0     1       1      0      1       1.1     1.1     1.1
4 R         0     3       3      0      3      NA       3       2  
5 X         1     1       1      1      1.1     1.1     1.1     1.1
6 X         1     2       1      2      1.2     1.2     1.2     1.2

Or another option is using := while assignment

...
  mutate(!! paste0("alloc_", i) := index$concat[index$cumGrp==1][nmCnt])%>%
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM