1

I am trying to write a "for loop" to update my R data frame by iterating.

Here is my code:

datalist = list()

for (i in 1:5) { 
dat <- data.frame(ID=LETTERS[seq( from = 1, to = 20 )],nutrition=rnorm(20, mean=50, sd=10),
                Stage=c(rep("A1",5), rep("B1",15)))
dat$ADG<-dat$nutrition*0.05
dat$M_weight<-dat$nutrition*0.5+dat$ADG*100
dat$Age<-dat$M_weight*1.1+dat$ADG*0.6
dat$Stage<-as.character(dat$Stage)
dat$Stage[dat$ADG>=3]<-"C1" 
dat$i <- i  # maybe you want to keep track of which iteration produced it?
datalist[[i]] <- dat # add it to your list    # 



}

big_data = do.call(rbind, datalist)

From iteration 2, I would like to have "Stage" updated to "C1" if ADG is equal or greater than 3 but this would not apply to iteration 1.

Thank you so much! I appreciate any replies!

4
  • Not clear what you mean. The loop is doing what it should, since the iterator i is only used in one place. If you want some dependence on the previous iteration, maybe add an if (i > 1){ do stuff with i-1 } block? Commented Aug 2, 2017 at 20:00
  • 1
    Hi @Frank. Thanks. Yes, I want somewhat dependence on the previous iteration so I will try the block you mentioned. Thanks, I appreciate your answer. Commented Aug 2, 2017 at 20:03
  • 1
    @Joanna your code only updates Stage based on ADG but ADG never changes. How else should the data after iteration 1 differ from the original data? Commented Aug 2, 2017 at 21:15
  • Hi, @ChiPak. Thanks for reminding and I have my code edited. Now the ADG changed every iteration but I would like to apply something from the SECOND iteration. Commented Aug 3, 2017 at 19:57

1 Answer 1

1

I think you want a recursive function instead of an iterative one

Your data stringsAsFactors=F

dat <- data.frame(ID=LETTERS[seq( from = 1, to = 20 )], nutrition=rnorm(20, mean=50, sd=10), Stage=c(rep("A1",5), rep("B1",15)), stringsAsFactors=F)

Use tidyverse for dplyr and purrr verbs

library(tidyverse)
special <- function( dat, counter, end ) { 
                 dat1 <- dat %>%
                       mutate(ADG = nutrition*0.05) %>%
                       mutate(M_weight = nutrition*0.5 + ADG*100) %>%
                       mutate(Age = M_weight*1.1 + ADG*0.6) %>%
                       mutate(Stage = ifelse( ADG >= 3, "C1", Stage )) %>%
                       mutate(i=counter)
                 if (counter < end) {
                       special(dat1, counter+1, end) 
                 } else {
                       return(dat1)
                 }                   
            }

desired <- map_df(2:5, ~special(dat,1,.x))

head(desired)

   ID nutrition Stage      ADG M_weight      Age i
1   A  47.17826    A1 2.358913 259.4804 286.8438 2
2   B  64.55988    C1 3.227994 355.0794 392.5241 2
3   C  52.29020    A1 2.614510 287.5961 317.9244 2
4   D  59.96544    A1 2.998272 329.8099 364.5899 2

Let me know if this is not the output you were expecting

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Chi Pak. Combined the "desired" and the first data frame is exactly what I want. I appreciate your help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.