lizzie
lizzie

Reputation: 606

Trying to create a dataframe as result of a loop

I'm trying to create a data frame that is a result of a loop:

variation <- seq(0.10, 3, 0.5)
for (i in seq_along(variation)) {
  x <- iris %>% mutate(newLength = Sepal.Length + variation[i])
  newSum <- x %>% summarise(newSum = sum(newLength))
  oldSum <- iris %>% summarise(oldSum = sum(Sepal.Length))

  df <- cbind(variation[i], oldSum, newSum)
  z <- rbind(df)
  print(z)
}

The output I'm getting is:

  variation[i] oldSum newSum
1          0.1  876.5  891.5
  variation[i] oldSum newSum
1          0.6  876.5  966.5
  variation[i] oldSum newSum
1          1.1  876.5 1041.5
  variation[i] oldSum newSum
1          1.6  876.5 1116.5
  variation[i] oldSum newSum
1          2.1  876.5 1191.5
  variation[i] oldSum newSum
1          2.6  876.5 1266.5

My desired output is:

 variation[i] oldSum newSum
         0.1  876.5  891.5
         0.6  876.5  966.5
         1.1  876.5 1041.5
         1.6  876.5 1116.5
         2.1  876.5 1191.5
         2.6  876.5 1266.5

What am I doing wrong?

Upvotes: 1

Views: 43

Answers (2)

thelatemail
thelatemail

Reputation: 93938

You should try a vectorized function like outer to do the main complicated part of your analysis:

data.frame(
  variation,
  oldSum=sum(iris$Sepal.Length),
  newSum=colSums(outer(iris$Sepal.Length, variation, FUN=`+`))
)

#  variation oldSum newSum
#1       0.1  876.5  891.5
#2       0.6  876.5  966.5
#3       1.1  876.5 1041.5
#4       1.6  876.5 1116.5
#5       2.1  876.5 1191.5
#6       2.6  876.5 1266.5

As @Frank notes, you could simplify/speed this up even further:

sum.sl <- sum(iris$Sepal.Length)
data.frame(
  variation,
  oldSum=sum.sl,
  newSum=sum.sl + length(iris$Sepal.Length)*variation
)

Upvotes: 3

Duncan
Duncan

Reputation: 151

rbind() binds multiple rows together. If you just give it one df, it will just return that data frame. Try rbind(z,df) to append the new DF to the old z.

variation <- seq(0.10, 3, 0.5)
for (i in seq_along(variation)) {
  x <- iris %>% 
    mutate(newLength = Sepal.Length + variation[i])
newSum <- x %>% 
    summarise(newSum = sum(newLength))
oldSum <- iris %>% 
  summarise(oldSum = sum(Sepal.Length))    
df <- cbind(variation[i], oldSum, newSum)
z <- rbind(z,df)
print(z)
}

Note that the z won't be cleared out, so you may wish to initialize it before you start your loop. Something like z = NULL would work to make sure it was empty.

Upvotes: 3

Related Questions