SCW SCW - 1 month ago 7
R Question

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" ...

Answer Source

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 ] 
} 
}