Targets dynamic branching to add columns to matrix

145 views Asked by At

I have multiple rasters in a R targets pipeline that I load with tar_files() and then iterate over it in the next target to add one column per file to a matrix. However, only the first column is created. Here is a reprex without using files:

library(targets)

tar_script(
  {
    add_column <- function(letter) {
      matrix(rep(letter, 10), ncol = 1)
    }
    list(
      tar_target(letters, letters),
      tar_target(
        added_columns,
        add_column(letters),
        pattern = map(letters)
      )
    )
  },
  ask = FALSE
)
tar_make()

How I can get a matrix with a column for each iteration?

When I load the result using tar_load(add_columns) it only has the first column. In the case with rasters, I used terra::extract to get one vector for each iteration, when I load the result, there are all columns but filled with NA except the first one.

2

There are 2 answers

0
landau On BEST ANSWER

I agree with @Radim, and you can produce their mat matrix by using nrow = 1 instead of ncol = 1 in matrix(), then transposing the result. Same solution, just a different way of thinking about it. iteration = "vector" row-binds data-frame-like objects, so the idea is to have each dynamic branch create one row instead of one column.

library(targets)
add_column <- function(letter) {
  matrix(rep(letter, 10), nrow = 1) # switch to nrow = 1
}
list(
  tar_target(letters, letters),
  tar_target(
    mat,
    add_column(letters),
    pattern = map(letters)
  ),
  tar_target(transposed, t(mat)) # transpose the output
)
3
Radim On
  1. It strikes me - because you are looking for a single output in the end, not for branching of your pipeline - that this is something that would be better achieved inside a target instead of using targets to do a programming job.

  2. That being said, would this be what you are looking for?

library(targets)
tar_script(
  {
    add_column <- function(letter) {
      matrix(rep(letter, 10), ncol = 1)
    }
    list(
      tar_target(
        name = letters, 
        command = letters
        ),
      tar_target(
        name = added_columns,
        command = add_column(letters),
        pattern = map(letters)
      ),
      tar_target(
        name = mat,
        command = matrix(added_columns, ncol = 10, byrow = TRUE),
      )
    )
  },
  ask = FALSE
)
tar_make()
tar_load(mat)

With the default settings, tar_target() uses iteration = "vector", so the target that uses pattern = map() will return a named vector.