2

I am attempting to plot multiple data tables that share a column name pattern using a function. Below are two sample tables:

dt1 = data.table(date=seq(as.Date("2015/06/20"), as.Date("2015/06/29"), by= "day"),
             ppp_min = rnorm(10), ppp_mean = rnorm(10), ppp_max = rnorm(10))
dt2 = data.table(date=seq(as.Date("2015/06/20"), as.Date("2015/06/29"), by= "day"),
             qqq_min = rnorm(10), qqq_mean = rnorm(10), qqq_max = rnorm(10))

And a sample plot function:

plt <- function(dt,code) {
min <- paste(code, '_min',sep='')
plot(dt$date, dt[,get(min)])
}
plt(dt1,ppp)
plt(dt2,qqq)

The function allows to specify the data table to plot. The "code" in the function is used to apply relevant titles and write file names but coincidentally matches the variable in the column names. This is an application of Get columns by string from data.table

My question is: Is it possible to do a pattern match instead? I have tried to do this using grep and applying eval() and quote() as suggested in the question pass column name in data.table using variable in R

I have attempted doing something like:

plot(dt$date, dt[,grep("min",names(dt))])

My reasoning for attempting a pattern match is that I have multiple colnames I am plotting and the first solution seems recursive. In this instance the "code" matches the variable but what if it didn't and I still want to pattern match?

Thanks

Community
  • 1
  • 1
ghostpuppy
  • 63
  • 5
  • 1
    Maybe `plt <- function(dt, code) { plot(dt$date, unlist(dt[, paste0(code, '_min'), with = FALSE])) } ; plt(dt1, 'ppp') ; plt(dt2, 'qqq')` – alistaire May 22 '16 at 03:49
  • 1
    I think the only problem is the missing with=FALSE (shown in alistaire's comment). Alternately, `[[` like `plt = function(dt) plot(dt$date, dt[[grep("min",names(dt))]])` – Frank May 22 '16 at 03:56
  • 1
    You know you can also use `plot` inside `[` in "data.table", right? Like `dt1[, plot(.SD), .SDcols = c("date", grep("min", names(dt1), value = TRUE))]`. – A5C1D2H2I1M1N2O1R2T1 May 22 '16 at 05:06
  • @Frank, your suggestion seems to be the solution. I had attempted a variation of this but somehow missed this application. It answers the question thanks! I will post the solution. – ghostpuppy May 22 '16 at 14:15

2 Answers2

2

Using data tables %like% function will get you what you want without needing to create a function. Depending on what you're looking for here are several options:

plot(dt1[,.SD, .SDcols=names(dt1) %like% "date|_min$"])

dt1[,lapply(.SD, plot, date), .SDcols=names(dt1) %like% "_min$"]

code <- c("ppp", "qqq")
plot(dt1[,.SD, .SDcols=names(dt1) %like% sprintf("date|(%s)_min$", paste(code, collapse="|"))])
maazza
  • 7,016
  • 15
  • 63
  • 96
manotheshark
  • 4,297
  • 17
  • 30
1

Frank's suggested answer is the most straight forward. It was tested to plot large data tables with a higher level of complexity and worked! The simplified function that works with the sample tables is found below.

plt <- function(dt,code) {
plot(dt$date, dt[[grep("min",names(dt))]])
}
plt(dt1,ppp)
plt(dt2,qqq)
ghostpuppy
  • 63
  • 5