Search code examples
rwrite.table

Write.table as text file with differing number of rows


I want to share the output of my analysis in R with someone as a txt file. I can do this one here that I know of:

write.table(S$MainInformation,  file = "Output.txt",
  row.names = FALSE, sep = "\t", 
  quote = FALSE, fileEncoding = "UTF-8", append = TRUE)

write.table(S$AnnualProduction,  file = "Output.txt",
  row.names = FALSE, sep = "\t", 
  quote = FALSE, fileEncoding = "UTF-8", append = TRUE)

write.table(S$AnnualGrowthRate,  file = "Output.txt",
  row.names = FALSE, sep = "\t", 
  quote = FALSE, fileEncoding = "UTF-8", append = TRUE)

write.table(S$MostProdAuthors,  file = "Output.txt",
  row.names = FALSE, sep = "\t", 
  quote = FALSE, fileEncoding = "UTF-8", append = TRUE)

The documents are thus combined into one txt file. However, if I want to do it in one step, i.e. S rather than S$, I get an error code, not surprisingly, that the argumetns imply differing number of rows.

write.table(S,  file = "Output.txt",
   row.names = FALSE, sep = "\t", 
   quote = FALSE, fileEncoding = "UTF-8")

Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, : arguments imply differing number of rows: 16, 25, 1, 10

Of course, I don't care about that... I don't know yet how to work with lapply which could be helpful_ Thanks! SCW

 str(S)
List of 9
 $ MainInformation  : chr [1:16] "\n\nMain Information about data\n\n" "Articles                              1374 \n" "Sources (Journals, Books, etc.)       736 \n" "Keywords Plus (ID)                    1172 \n" ...
 $ AnnualProduction :'data.frame':  25 obs. of  2 variables:
  ..$ Year    : Factor w/ 25 levels "1985","1988",..: 1 2 3 4 5 6 7 8 9 10 ...
  ..$ Articles: int [1:25] 1 1 1 1 3 1 2 2 3 2 ...
 $ AnnualGrowthRate : num 20.9
 $ MostProdAuthors  :'data.frame':  10 obs. of  4 variables:
  ..$ Authors                :Class 'AsIs'  chr [1:10] "NYE,J.      " "GRIX,J      " "OGUNNUBI,O  " "PAMMENT,J   " ...
  ..$ Articles               :Class 'AsIs'  chr [1:10] "16" " 8" " 8" " 8" ...
  ..$ Authors                :Class 'AsIs'  chr [1:10] "NYE,J.    " "PAMMENT,J " "CHONG,A   " "LEE,J     " ...
  ..$ Articles Fractionalized:Class 'AsIs'  chr [1:10] "16.00" " 8.00" " 6.00" " 5.00" ...
 $ MostCitedPapers  :'data.frame':  10 obs. of  3 variables:
  ..$ Paper         :Class 'AsIs'  chr [1:10] "SANTOS F;EISENHARDT K,(2009),ACAD. MANAGE. J.                                            " "HYDE-PRICE A,(2006),J. EUR. PUBLIC POLICY                                                " "NYE J.,(2008),ANN. AM. ACAD. POLIT. SOC. SCI.                                            " "NYE J.,(2003),THE PARADOX OF AM. POWER: WHY THE WORLD'S ONLY SUPERPOWER CAN'T GO IT ALONE" ...
  ..$ TC            :Class 'AsIs'  chr [1:10] "262" "133" "120" "119" ...
  ..$ TCperYear     :Class 'AsIs'  chr [1:10] "32.75" "12.09" "13.33" " 8.50" ...
 $ MostProdCountries:'data.frame':  10 obs. of  3 variables:
  ..$ Country  :Class 'AsIs'  chr [1:10] "USA           " "ENGLAND       " "AUSTRALIA     " "CHINA         " ...
  ..$ Articles :Class 'AsIs'  chr [1:10] "255" " 96" " 81" " 67" ...
  ..$ Freq     :Class 'AsIs'  chr [1:10] "0.2621" "0.0987" "0.0832" "0.0689" ...
 $ TCperCountries   :'data.frame':  10 obs. of  3 variables:
  ..$ Country                  :Class 'AsIs'  chr [1:10] "USA           " "ENGLAND       " "AUSTRALIA     " "UNITED KINGDOM" ...
  ..$ Total Citations          :Class 'AsIs'  chr [1:10] "1701" " 708" " 303" " 297" ...
  ..$ Average Article Citations: chr [1:10(1d)] "6.671" "7.375" "3.741" "6.319" ...
  .. ..- attr(*, "dimnames")=List of 1
  .. .. ..$ CO: chr [1:10] "USA" "ENGLAND" "AUSTRALIA" "UNITED KINGDOM" ...
 $ MostRelSources   :'data.frame':  10 obs. of  2 variables:
  ..$ Sources       :Class 'AsIs'  chr [1:10] "INTERNATIONAL JOURNAL OF THE HISTORY OF SPORT                                         " "INTERNATIONAL JOURNAL OF COMMUNICATION                                                " "INTERNATIONAL JOURNAL OF CULTURAL POLICY                                              " "JOURNAL OF CONTEMPORARY CHINA                                                         " ...


..$ Articles      :Class 'AsIs'  chr [1:10] "19" "16" "16" "14" ...
$ MostRelKeywords  :'data.frame':   10 obs. of  4 variables:
..$ Author Keywords (DE)     :Class 'AsIs'  chr [1:10] "SOFT POWER        " "CHINA             " "PUBLIC DIPLOMACY  " "FOREIGN POLICY    " ...
..$ Articles                 :Class 'AsIs'  chr [1:10] "387" "119" " 74" " 50" ...
..$ Keywords-Plus (ID)       :Class 'AsIs'  chr [1:10] "SOFT POWER      " "FOREIGN POLICY  " "POLITICS        " "CHINA           " ...
..$ Articles                 :Class 'AsIs'  chr [1:10] "112" " 47" " 41" " 39" ...

Solution

  • Is the file meant to be primarily human-readable or machine-readable?

    If human-readable, capture.output() as suggested above should be sufficient.

    lst <- list(a=1:8, 
                b=1.2e+11, 
              df1=data.frame(foo=1:5/4, bar=1:5/3), 
              df2=as.data.frame(matrix(runif(16), 4)))
    capture.output(lst, file="list.txt")
    

    Otherwise, if you insist on putting things side-by side, this might be an option

    max_l <- max(rapply(lst, length))
    as.data.frame(rapply(lst, function(x) 'length<-'(x, max_l), how="list"))
    
    #    a       b df1.foo   df1.bar    df2.V1    df2.V2    df2.V3     df2.V4
    # 1  1 1.2e+11    0.25 0.3333333 0.3978436 0.1971467 0.5619881 0.01103607
    # 2  2      NA    0.50 0.6666667 0.9556758 0.1153423 0.7327180 0.90631526
    # 3  3      NA    0.75 1.0000000 0.6533494 0.9959655 0.8708056 0.77065363
    # 4  4      NA    1.00 1.3333333 0.3287437 0.3792767 0.5721703 0.38250462
    # 5  5      NA    1.25 1.6666667        NA        NA        NA         NA
    # 6  6      NA      NA        NA        NA        NA        NA         NA
    # 7  7      NA      NA        NA        NA        NA        NA         NA
    # 8  8      NA      NA        NA        NA        NA        NA         NA
    

    and then write it to file as any other data.frame.

    If the file is meant to be primarily machine-readable, maybe the results are to be further processed using some other software, a better approach would be to use a more specialized file format than plain text. Something like JSON or XML.

    Writing to JSON is as simple as

    library(RJSONIO)
    write(toJSON(lst), file="list.json")
    

    The resulting file is still fairly human-readable, I think.

    {
    "a": [ 1, 2, 3, 4, 5, 6, 7, 8 ],
    "b": 1.2e+11,
    "df1": {
     "foo": [   0.25,    0.5,   0.75,      1,   1.25 ],
     "bar": [ 0.33333, 0.66667,      1, 1.3333, 1.6667 ] 
    },
    "df2": {
     "V1": [ 0.094046, 0.049654, 0.82116, 0.82932 ],
     "V2": [ 0.65473, 0.13283, 0.34181, 0.73137 ],
     "V3": [ 0.90729, 0.6962, 0.24158, 0.64411 ],
     "V4": [ 0.28075, 0.95764, 0.1584, 0.41834 ] 
    } 
    }