Home > database >  Appending List Elements in write.table
Appending List Elements in write.table

Time:07-19

I have a list of what are essentially tables of different variables, with a reproducible dummy example below (it's a little ugly, but it gets the idea across).

results <- list()
for(ii in names(iris)[1:4]) {
  mytab <- table(iris[,i] > mean(iris[,i]), iris$Species)
  myp <- chisq.test(mytab)$p.value
  results[[ii]] <- as.data.frame(cbind(mytab, P.value=myp))
  results[[ii]] <- tibble::rownames_to_column(results[[ii]], ii)
}

In a previous version R (at least 4.0), I used to be able to do something like:

lapply(results, function(x) write.table(x, "myfile.txt", append=T, sep="\t", quote=F, row.names=F))

which would generate a file called myfile.txt and fill it with all of my tables, much like the list of printed tables from results. I've had this code (which was functioning as expected) since at least the end of 2021. However, I now get the error:

Error in write.table(x, "myfile.txt", append = T, sep = "\t", quote = T,  : 
  (converted from warning) appending column names to file

And to some extent I get it -- the column names I'm using aren't identical to what I'm appending, but I don't really care for my purposes. I just want my printed list of tables. Is there a way to force appending irrespective of mismatched column names? I've tried using col.names=NA but then receive the error that using col.names=NA with row.names=F "makes no sense". Do I need to resign myself to using functions like sink for this? I'd really like everything to remain tab-separated if possible.

CodePudding user response:

It appears to be baked-in, depending solely on the col.names and append arguments and no easy way to squelch it there.

In general it's just a warning, but since it was elevated to Error status, that suggests you've set options(warn = 2) or higher. It's not a factor for these resolutions (which result in no warning being emitted and therefore no escalation to an error).

  1. Suppress it and all other warnings (for good or bad):

    write.table(data.frame(a=1,b=2), "quux.csv", append=T, sep="\t", quote=F, row.names=F)
    # Error in write.table(data.frame(a = 1, b = 2), "quux.csv", append = T,  : 
    #   (converted from warning) appending column names to file
    
    suppressWarnings(write.table(data.frame(a=1,b=2), "quux.csv", append=T, sep="\t", quote=F, row.names=F))
    ### nothing emitted, file appended
    
  2. Suppress just that warning, allowing others (since suppressing all can hide other issues):

    withCallingHandlers(
      write.table(data.frame(a=1,b=2), "quux.csv", append=T, sep="\t", quote=F, row.names=F),
      warning = function(w) {
        if (grepl("appending column names to file", conditionMessage(w))) { 
          invokeRestart("muffleWarning")
        }
      })
    ### nothing emitted, file appended
    
    withCallingHandlers(
      write.table(data.frame(a=1,b=2), "quux.csv", append=T, sep="\t", quote=F, row.names=F),
      warning = function(w) {
        if (grepl("something else", conditionMessage(w))) { 
          invokeRestart("muffleWarning")
        }
      })
    # Error in write.table(data.frame(a = 1, b = 2), "quux.csv", append = T,  : 
    #   (converted from warning) appending column names to file
    

CodePudding user response:

Another potential solution is to use write.list() from the erer package:

library(erer)
#> Loading required package: lmtest
#> Loading required package: zoo
#> 
#> Attaching package: 'zoo'
#> The following objects are masked from 'package:base':
#> 
#>     as.Date, as.Date.numeric
#> Registered S3 method overwritten by 'quantmod':
#>   method            from
#>   as.zoo.data.frame zoo

results <- list()
for(ii in names(iris)[1:4]) {
  mytab <- table(iris[,ii] > mean(iris[,ii]), iris$Species)
  myp <- chisq.test(mytab)$p.value
  results[[ii]] <- as.data.frame(cbind(mytab, P.value=myp))
  results[[ii]] <- tibble::rownames_to_column(results[[ii]], ii)
}
write.list(z = results, file = "myfile.txt", row.names = FALSE, quote = FALSE)
read.csv("~/Desktop/myfile.txt")
#>          Result Sepal.Length setosa versicolor virginica      P.value
#> 1  Sepal.Length        FALSE     50         24         6 8.373761e-18
#> 2  Sepal.Length         TRUE      0         26        44 8.373761e-18
#> 3                                                                    
#> 4        Result  Sepal.Width setosa versicolor virginica      P.value
#> 5   Sepal.Width        FALSE      8         42        33  1.24116e-11
#> 6   Sepal.Width         TRUE     42          8        17  1.24116e-11
#> 7                                                                    
#> 8        Result Petal.Length setosa versicolor virginica      P.value
#> 9  Petal.Length        FALSE     50          7         0 9.471374e-28
#> 10 Petal.Length         TRUE      0         43        50 9.471374e-28
#> 11                                                                   
#> 12       Result  Petal.Width setosa versicolor virginica      P.value
#> 13  Petal.Width        FALSE     50         10         0 4.636126e-26
#> 14  Petal.Width         TRUE      0         40        50 4.636126e-26
#> 15

# You can also specify the table names, e.g.
write.list(z = results, file = "myfile2.txt", row.names = FALSE, quote = FALSE, t.name = 1:4)
read.csv("~/Desktop/myfile2.txt")
#>    Result Sepal.Length setosa versicolor virginica      P.value
#> 1       1        FALSE     50         24         6 8.373761e-18
#> 2       1         TRUE      0         26        44 8.373761e-18
#> 3                                                              
#> 4  Result  Sepal.Width setosa versicolor virginica      P.value
#> 5       2        FALSE      8         42        33  1.24116e-11
#> 6       2         TRUE     42          8        17  1.24116e-11
#> 7                                                              
#> 8  Result Petal.Length setosa versicolor virginica      P.value
#> 9       3        FALSE     50          7         0 9.471374e-28
#> 10      3         TRUE      0         43        50 9.471374e-28
#> 11                                                             
#> 12 Result  Petal.Width setosa versicolor virginica      P.value
#> 13      4        FALSE     50         10         0 4.636126e-26
#> 14      4         TRUE      0         40        50 4.636126e-26
#> 15

Created on 2022-07-19 by the reprex package (v2.0.1)

  •  Tags:  
  • r
  • Related