1

I'm trying to run a loop with multiple dataframes. I'm using the gather function from tidyr and I want to use as argument the index of the loop, i, along with a word, deaths.

I've been trying:

gather(data[[i]], "year", paste("deaths", i, sep="_"), 2:ncol(data[[i]]))

However, everytime I try that, it returns "Error: Must supply a symbol or a string as argument".

I read somewhere that tidyr evaluates things in a non-standard way and that the alternative is gather_, which uses standard evaluation.

However, the command

gather_(data[[i]], "year", paste("deaths", i, sep="_"), 2:ncol(data[[i]]))

Returns Error: Only strings can be converted to symbols.

However, I tought the paste command was already resulting in a string.

Anyone knows a fix?

Here is the full error:

"<error>
message: Only strings can be converted to symbols
class:   `rlang_error`
backtrace:
 -tidyr::gather_(...)
 -tidyr:::gather_.data.frame(...)
 -rlang::syms(gather_cols)
 -rlang:::map(x, sym)
 -base::lapply(.x, .f, ...)
 -rlang:::FUN(X[[i]], ...)
Call `summary(rlang::last_error())` to see the full backtrace"

The full code:

require(datasus)
require(tidyr)

data_list <- list()

for(i in 1:2){
  data_list[[i]] <- sim_inf10_mun(linha = "Município", coluna = "Ano do Óbito", periodo = c(1996:2016), municipio = "all", 
                                  capitulo_cid10 = i)
  data_list[[i]] <- data.frame(data_list[i])
  data_list[[i]] <- data_list[[i]][-1,]
  data_list[[i]] <- data_list[[i]][,-ncol(data_list[[i]])]
  data_list[[i]] <- gather(data_list[[i]], "ano", "deaths_01_i", 2:ncol(data_list[[i]])) 
  names(data_list[[i]])[1]<-"cod_mun"
  data_list[[i]] <- transform(data_list[[i]], cod_mun = substr(cod_mun, 1, 6))
  data_list[[i]] <- transform(data_list[[i]], ano = substr(ano, 2, 5))
}

This returns a panel dataset exactly the way I want, with (municipality code-year) identification in lines, and a value. My problem is that the value (column) name is "deaths_01_i", which is kinda obvious since it is quotation marks, whereas I wanted it to run with the loop. Thus I tried to implement it with a paste.

I know I can just change the variable name by adding a line names(data_list[[i]])[3]<-paste("deaths_01",i,sep="_"), but the problem got my attention to improving my understanding of the code.

Some words are in Portuguese but they are irrelevant to the problem. I also changed the range of the loop to avoid time issues.

jpugliese
  • 261
  • 1
  • 11
  • 3
    Providing same sample data and desired output would increase the chances for an actual solution. – Wimpel Nov 09 '18 at 16:17
  • 2
    Please provide sample code, the problem is elsewhere: functional programming + tidyverse + for loop = you are doing something very wrong. – JohnCoene Nov 09 '18 at 16:19
  • @JohnCoene thanks for the reply, I've provided the sample code. The data is downloaded directly using the code. – jpugliese Nov 09 '18 at 16:28
  • @Wimpel thanks for the reply, I've provided the sample code. The data is downloaded directly using the code. – jpugliese Nov 09 '18 at 16:28
  • try add double "!" before your paste(), such like `gather(data[[i]], "year", !!paste("deaths", i, sep="_"), 2:ncol(data[[i]]))` – Darren Tsai Nov 09 '18 at 17:03
  • @DarrenTsai That works! Want to add it as an answer so I can mark it right? Also, the running time increased by two-fold. And I've trying adding the "!!" in front of the `i`... Care to explain what is happening exactly when I add that in front of the paste? Thanks! – jpugliese Nov 09 '18 at 17:22
  • https://stackoverflow.com/q/26497751/10068985 : This question has a similar problem with yours. And you can look up **"quasiquotation"** here: https://adv-r.hadley.nz/quasiquotation.html – Darren Tsai Nov 09 '18 at 17:35

0 Answers0