1

I have a dataframe df:

Shares    Price1    Price2    Price3
100       9         10        11
200       5         6         7
300       3         2         1

And I would like to loop over this dataframe and create three new columns equal to Shares x Price[i] where (i in 1:3). I tried the following code:

for (j in 1:3) {
  df$paste0("MktCap",j,sep="")<-df$Shares*df$paste0("Price",j,sep="")
}

But I get the error:

Error: attempt to apply non-function

I've looked here but it's not quite what I want as I would like my new column names to iterate.

1
  • what is your expected output Commented Jul 29, 2017 at 22:43

3 Answers 3

3

Is this what you want ? also, check the link here http://www.statmethods.net/management/subset.html

for (j in 1:3) {
  df[,paste0("MktCap",j,sep="")]<-df$Shares*df[,paste0("Price",j,sep="")]
}


> df
  Shares Price1 Price2 Price3 MktCap1 MktCap2 MktCap3
1    100      9     10     11     900    1000    1100
2    200      5      6      7    1000    1200    1400
3    300      3      2      1     900     600     300
Sign up to request clarification or add additional context in comments.

Comments

1

@Wen's solution works, and if you have many price columns it would be the way to go. But I think using dplyr you get a much more expressive solution that is easier to read and understand:

library(dplyr)

df <- data.frame(Shares = c(100, 200, 300), Price1 = c(9, 5, 3), Price2 = c(10, 6, 2), Price3 = c(11, 7, 1))

(df <- df %>%
  mutate(MktCap1 = Shares * Price1,
         MktCap2 = Shares * Price2,
         MktCap3 = Shares * Price3))

  Shares Price1 Price2 Price3 MktCap1 MktCap2 MktCap3
1    100      9     10     11     900    1000    1100
2    200      5      6      7    1000    1200    1400
3    300      3      2      1     900     600     300

Comments

1

Consider the data frame, df:

df = tribble(
~Shares,    ~Price1,    ~Price2,    ~Price3,
100,        9,          10,         11,
200,        5,          6,          7,
300,        3,          2,          1
)

First approach - Terrible. Hard coding. This works, but you want a reproducible solution.

df$Value1 = df$Shares * df$Price1
df$Value2 = df$Shares * df$Price2
df$Value3 = df$Shares * df$Price3

Second approach - Better, but still not great. Subset orginal data frame for values, multiply by prices, assign colnames, merge the data together

stockPrice = df[,2:4]
stockValue = df$Shares * stockPrice
colnames(stockValue) = c(paste("value", seq(1:3), sep = ""))
cbind(df, stockValue)

Third (best) approach - define a function!

calculateValues = function(df){
  N = ncol(df)
  L = N-1
  stockPrice = df[,2:N]
  stockValue = df$Shares * stockPrice
  colnames(stockValue) = c(paste("value", seq(1:L), sep = ""))
  cbind(df, stockValue)
}

calculateValues(df)

This should output a new data frame with shares * values each time, named and everything! The only catch is that the first column of your df has to be named "Shares" every time.

Comments

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.