Красиво экспортируйте список матриц на тот же лист в Excel

У меня есть список из 4 матриц. Первые два из них:

$`1857-1903`
                      Bank.o.kassa Obligationer       Lån    Aktier Placeringar.andra.ftg Fodringar Reala.tillgångar Övriga.tillgångar
Bank.o.kassa             1.0000000    0.8014382 0.8079718 0.4421687                    NA 0.8395201        0.9144023         0.7995480
Obligationer             0.8014382    1.0000000 0.8422192 0.4590398                    NA 0.7871074        0.8815054         0.7003110
Lån                      0.8079718    0.8422192 1.0000000 0.5476716                    NA 0.8932723        0.9295665         0.7846206
Aktier                   0.4421687    0.4590398 0.5476716 1.0000000                    NA 0.7203681        0.4221815         0.6281095
Placeringar.andra.ftg           NA           NA        NA        NA                     1        NA               NA                NA
Fodringar                0.8395201    0.7871074 0.8932723 0.7203681                    NA 1.0000000        0.8869905         0.9395209
Reala.tillgångar         0.9144023    0.8815054 0.9295665 0.4221815                    NA 0.8869905        1.0000000         0.8158413
Övriga.tillgångar        0.7995480    0.7003110 0.7846206 0.6281095                    NA 0.9395209        0.8158413         1.0000000
Kapitalinkomster         0.9163688    0.8960790 0.9318508 0.4985449                    NA 0.9277740        0.9821501         0.8755644
                      Kapitalinkomster
Bank.o.kassa                 0.9163688
Obligationer                 0.8960790
Lån                          0.9318508
Aktier                       0.4985449
Placeringar.andra.ftg               NA
Fodringar                    0.9277740
Reala.tillgångar             0.9821501
Övriga.tillgångar            0.8755644
Kapitalinkomster             1.0000000

$`1904-1948`
                      Bank.o.kassa Obligationer         Lån       Aktier Placeringar.andra.ftg   Fodringar Reala.tillgångar Övriga.tillgångar
Bank.o.kassa             1.0000000   -0.5636371  0.12902979 -0.658883574          -0.202688601  0.76474140       0.81544129         0.4642105
Obligationer            -0.5636371    1.0000000  0.23820065  0.369712399           0.649156560 -0.69097442      -0.67090178        -0.3108845
Lån                      0.1290298    0.2382006  1.00000000 -0.301682319           0.663984986 -0.07873989       0.00901089         0.2894697
Aktier                  -0.6588836    0.3697124 -0.30168232  1.000000000          -0.005049947 -0.69634496      -0.77966741        -0.7496402
Placeringar.andra.ftg   -0.2026886    0.6491566  0.66398499 -0.005049947           1.000000000 -0.44833419      -0.31431360         0.1089602
Fodringar                0.7647414   -0.6909744 -0.07873989 -0.696344963          -0.448334185  1.00000000       0.84590718         0.5765548
Reala.tillgångar         0.8154413   -0.6709018  0.00901089 -0.779667406          -0.314313596  0.84590718       1.00000000         0.5367746
Övriga.tillgångar        0.4642105   -0.3108845  0.28946968 -0.749640198           0.108960190  0.57655477       0.53677459         1.0000000
Kapitalinkomster        -0.1114329    0.3693150  0.38160001 -0.125296598           0.720230427 -0.17280772      -0.13946215         0.3720201
                      Kapitalinkomster
Bank.o.kassa                -0.1114329
Obligationer                 0.3693150
Lån                          0.3816000
Aktier                      -0.1252966
Placeringar.andra.ftg        0.7202304
Fodringar                   -0.1728077
Reala.tillgångar            -0.1394622
Övriga.tillgångar            0.3720201
Kapitalinkomster             1.0000000

Я хочу экспортировать их на тот же рабочий лист в Excel. Проблема в том, что если я, например, делаю write.csv2(my.list,file="my.list.csv2") матрицы не разделены, между ними нет промежутка. С другой стороны, я знаю, как использовать XLConnect для экспорта моего списка в книгу с несколькими листами (в данном случае 4). Но я хочу, чтобы мои матрицы находились на одном листе, разделенные некоторым интервалом, с именами списков (например, $1857-1903). И было бы неплохо, если бы присутствовали имена строк... Возможно ли это? Не смог найти ответа. Наилучшие пожелания!

Изменить:

Я принял ответ @January. Спасибо! Но если я использую write.csv2 вместо write.table (чтобы получить желаемый результат), я получаю предупреждающее сообщение:

In write.csv2(export, file = "funkcorr.csv", quote = F, sep = ",") : attempt to set 'sep' ignored. Затем числа в Excel имеют . вместо ,. Итак, мне нужно вручную преобразовать . в , в Excel. Есть идеи, почему sep игнорируется?


person user1665355    schedule 22.10.2012    source источник
comment
Попробуйте sink("my.list.txt"); my.list; sink(), а затем откройте его в Excel как файл с разделителями-пробелами. У меня отлично работает в LibreOffice, но у меня нет доступа к Excel, чтобы проверить это.   -  person A5C1D2H2I1M1N2O1R2T1    schedule 22.10.2012
comment
Re the Edit: были ли определены ваши данные в форме write.csv2()? Нет? Тогда не используйте его! write.csv() и др. были написаны как удобные обертки для 2 распространенных стандартов файлов CSV. Они сами вызывают write.table() с подходящими значениями по умолчанию. Они игнорируют другие аргументы, поскольку они не определяют CSV-файл в ожидаемом языковом стандарте. Почему вы хотите получить дополнительный вызов, используя write.csv2() вместо write.table(), мне совершенно непонятно. И в любом случае, как я уже упоминал, вы не можете, потому что некоторые аргументы жестко запрограммированы для представления разделителей в ожидаемых типах файлов.   -  person Gavin Simpson    schedule 22.10.2012


Ответы (3)


Ниже приведено решение на основе XLConnect:

# Preparation of dummy data
data = rep(list(WorldPhones), 5)
names(data) = LETTERS[1:5]

require(XLConnect)
wb = loadWorkbook("matrix.xlsx", create = TRUE)
# Create a new sheet
createSheet(wb, name = "mysheet")
# cumulative length (rows) of matrices
# +2 = 1 for list names, 1 for header row
cumlen = cumsum(c(1, head(sapply(data, nrow), n = -1) + 2))
# Write data rows (implicitly vectorized!)
writeWorksheet(wb, data = data, sheet = "mysheet", startRow = cumlen + 1, header = TRUE)
# Write list names
writeWorksheet(wb, data = as.list(names(data)), sheet = "mysheet", startRow = cumlen, header = FALSE)
saveWorkbook(wb)
person Martin Studer    schedule 22.10.2012

Изучив проблему немного подробнее, я все еще думаю, что вы можете получить что-то работоспособное с sink(), но я не уверен, есть ли варианты получше. Вот простой пример:

Пример данных

set.seed(1)
myList <- list(matrixA = matrix(sample(300, 60), nrow = 10,
                                dimnames = list(LETTERS[1:10], 
                                                paste0("V", 1:6))),
               matrixB = matrix(sample(300, 50), nrow = 10,
                                dimnames = list(LETTERS[1:10], 
                                                paste0("V", 1:5))))

Использование sink() и lapply()

sink("something.else.csv", type="output")
invisible(lapply(names(myList), 
                 function(x) { print(x)
                               dput(write.csv(myList[[x]])) } ))
sink()

Вот как выглядят полученные CSV-файлы:

[1] "matrixA"
"","V1","V2","V3","V4","V5","V6"
"A",80,296,262,131,214,120
"B",112,52,290,162,168,215
"C",171,198,182,133,202,109
"D",270,111,35,50,143,61
"E",60,221,74,286,136,291
"F",266,142,107,178,258,25
"G",278,204,4,210,6,78
"H",194,281,105,29,121,127
"I",184,108,237,190,185,161
"J",18,219,93,282,174,99
NULL
[1] "matrixB"
"","V1","V2","V3","V4","V5"
"A",274,297,122,65,171
"B",88,243,199,16,92
"C",137,100,112,173,70
"D",99,96,91,234,256
"E",193,298,209,208,163
"F",77,291,56,212,55
"G",141,246,195,121,33
"H",225,111,34,108,264
"I",25,220,67,213,233
"J",255,270,39,158,151
NULL

Это прекрасно открывается в любой программе для работы с электронными таблицами, и вы можете легко найти все экземпляры «NULL» и заменить их ничем, чтобы между каждой матрицей была пустая строка. Вы также можете, конечно, использовать write.csv2() вместо write.csv(), если это то, что вам нужно.

person A5C1D2H2I1M1N2O1R2T1    schedule 22.10.2012
comment
Спасибо! Узнал про мойку :) - person user1665355; 22.10.2012
comment
Конечно, проголосовал! Да, но если я опускаю аргумент sep, он все равно получает ., а не ,, поэтому мне все равно нужно вручную изменить его в Excel. В противном случае Excel не понимает, что значения являются числовыми..:/ - person user1665355; 22.10.2012
comment
@ user1665355, какую версию R вы используете? В R 2.15 мне кажется, что если вы что-то вводите для sep, это просто игнорируется. Кстати, аргумент, который вы, вероятно, ищете, это dec = (какой символ вы хотите использовать для десятичной дроби). Опять же, write.csv2 отключает это, но вы можете использовать write.table(object, file = somefile.tsv, sep = "\t", dec = ","), чтобы получить файл, разделенный TAB с запятой в качестве десятичного знака. - person A5C1D2H2I1M1N2O1R2T1; 22.10.2012
comment
Да, вероятно, я ищу dec, но он по-прежнему игнорируется.. Warning message: In write.csv2(export, file = "funkcorr.csv", dec = ",") : attempt to set 'dec' ignored :( Поэтому я просто пытаюсь найти способ импортировать dec="," в Excel. Я использую R 2.15 - person user1665355; 22.10.2012
comment
@user1665355 user1665355, да, как я уже упоминал в своем комментарии, вам нужно будет использовать write.table() для R, чтобы не игнорировать его. - person A5C1D2H2I1M1N2O1R2T1; 22.10.2012
comment
Да, но если я напишу write.table(export,file="funkcorr.csv",sep=";",dec=",",quote=FALSE), я все равно получу . вместо , странно... - person user1665355; 22.10.2012

Предполагая, что все матрицы имеют одинаковое количество столбцов и что список называется matrix.l:

export <- NULL
nc <- ncol( matrices.l[[1]] )

for( n in names( matrices.l ) ) 
  export <- rbind( export, c( n, rep( "", nc - 1 ) ), matrices.l[[n]], "" )

write.table( export, file= ...,  quote= F, sep= ",", ... )

Это не элегантно и делает смертным грехом создание объекта R в цикле for, но для четырех матриц подойдет.

person January    schedule 22.10.2012
comment
Спасибо! Он прекрасно работает, если не считать небольшого редактирования, которое я разместил в своем вопросе... С уважением! - person user1665355; 22.10.2012