简体   繁体   中英

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?

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.

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
)

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