Gin_Salmon
Gin_Salmon

Reputation: 847

Creating multiple columns in data table with a for loop

My data table looks like:

head(data)
    Date         AI   AGI      ADI   ASI   ARI   ERI   NVRI  SRI   FRI  IRI
1: 1991-09-06    NA 2094.19    NA    NA    NA    NA    NA    NA    NA    NA
2: 1991-09-13    NA 2204.94    NA    NA    NA    NA    NA    NA    NA    NA
3: 1991-09-20    NA 2339.10    NA    NA    NA    NA    NA    NA    NA    NA
4: 1991-09-27    NA 2387.81    NA    NA    NA    NA    NA    NA    NA    NA
5: 1991-10-04    NA 2459.94    NA    NA    NA    NA    NA    NA    NA    NA
6: 1991-10-11    NA 2571.07    NA    NA    NA    NA    NA    NA    NA    NA

Don't worry about the NAs. What I want to do is make a "percentage change" column for each of the columns apart from date.

What I've done so far is:

names_no_date <- unique(names(data))[!unique(names(data)) %in% "Date"]

for (i in names_no_date){
      data_ch <- data[, paste0(i, "ch") := i/shift(i, n = 1, type = "lag")-1]}

I get the error:

Error in i/shift(i, n = 1, type = "lag") : 
  non-numeric argument to binary operator

I'm wondering how I get around this error?

Upvotes: 1

Views: 2063

Answers (1)

Weihuang Wong
Weihuang Wong

Reputation: 13108

i is a string, so you are trying to divide a string in i/shift(i, n = 1, type = "lag"):

> "AI"/NA
Error in "AI"/NA : non-numeric argument to binary operator

Instead, do

for (i in names_no_date){
      data[, paste0(i, "ch") := get(i)/shift(get(i), n = 1, type = "lag")-1]
}

Also see Referring to data.table columns by names saved in variables.


Edit: @Frank writes in the comments that a more concise way to produce OP's output is

data[, paste0(names_no_date, "_pch") := .SD/shift(.SD) - 1, .SDcols=names_no_date]

Upvotes: 4

Related Questions