Передайте команды и результаты R из цикла for в файл

Мы хотим записывать команды и результаты R-скрипта в текстовый файл отчета. Канал в текстовый файл хорошо работает с sink(), но не в цикле for.

Скрипт вызывается с

source("myscript.r",echo=TRUE)

Нам нужен цикл для последовательного извлечения всех строк data.frame в вектор и выполнения некоторого векторного анализа с каждым вектором. Вот краткий пример:

#pipe output to file
sink("myfile.txt",append=TRUE,split=TRUE)
#some data
c1<-rnorm(10,mean=90,sd=10) 
c2<-rnorm(10,mean=75,sd=8)
c3<-rnorm(10,mean=98,sd=12)
#data in a data.frame
cData<-data.frame(c1,c2,c3)
#print data.frame
cData  
#loop over frame 
for (i in 1:ncol(cData))  
{
  #extract vector
  x<-cData[,i]
  #do something with vector
  n = length(x)
  #... more code
  #print result
  print(n)    
}
#close output
sink()

Я пробовал это с sink() и txtStart(), но sink() усекает команды и помещает результаты после цикла, txtStart(), похоже, повторяет команды, но не результаты.

Смотрел еще на brew, но мне нужен только текстовый файл, ничего не форматированный.


person Michael    schedule 13.01.2010    source источник


Ответы (3)


Несколько мыслей:

Результаты, поступающие после цикла, являются стандартным способом R для предоставления вывода, потому что R не выполняет цикл до тех пор, пока выражение не будет завершено. Это не проблема, характерная для sink. Чтобы увидеть это, выполните весь свой фрагмент кода, кроме команд sink (чтобы вывод попадал в консоль R), и вы увидите тот же эффект. Для ясности можно добавить строку типа

cat("Results for iteration", i, "\n")

в начале вашего цикла for.


Как отметил Джуба, вам, похоже, не нужен цикл for в этом случае, либо векторизация, либо apply были бы лучше.


Стандартный способ объединения кода и вывода в какую-либо форму отчета в R — использовать Sweave. Это создаст разметку Latex, которую вы затем сможете скомпилировать в документ PDF или PostScript (с небольшими усилиями, если у вас настроены некоторые инструменты Latex). Очевидным преимуществом этого является то, что вы также можете включать цифры.


РЕДАКТИРОВАТЬ: Существует также пакет brew для смешанного текста. и отчет по коду.

person Richie Cotton    schedule 15.01.2010
comment
Я согласен, усечение стандартно для R и экономит бумагу, но для моего отчета нужен полный исходный код. Кстати говоря, код R можно было бы векторизовать, но алгоритмы исходят из стандартов тестирования материалов и их легче понять (читателю отчета), когда они реализованы в цикле for. Наконец, я попробовал Sweave: он работает намного лучше, чем я себе представлял, и LaTeX-Output выглядит великолепно. - person Michael; 15.01.2010

Я бы рекомендовал не думать о

source("myscript.r",echo=TRUE)

а скорее с точки зрения Rscript (который идет с R)

Rscript myscript.r     # on windows, linux or os x

или с точки зрения littler

r myscript.r           # on linux or os x

Это дает вам возможность запрашивать параметры командной строки (через пакеты CRAN getopt и optparse) и многое другое.

person Dirk Eddelbuettel    schedule 13.01.2010

Я не уверен, что точно понимаю, чего вы хотите, в частности, почему вы хотите поместить исходный код в свой текстовый файл.

Во-первых, лучше использовать семейство функций *apply для просмотра фрейма данных вместо цикла for, особенно lapply и sapply.

С помощью следующего кода вы получите три разных представления вашего вывода. Первый должен быть похож на то, что вы получаете с вашим кодом. Второй и третий немного отличаются, они выводят значения в виде списка или фрейма данных.

sink("/tmp/myfile.txt", append=TRUE, split=TRUE)

myfunc <- function(v) {
  variance <- var(v)
  mean <- mean(v)
  return(list(variance=variance,mean=mean))
}

myotherfunc <- function(v) {
  cat("And the mean is:\n")
  print(mean(v))
  cat("And the variance is:\n")
  print(var(v))
}

# results printed directly
invisible(lapply(cData, myotherfunc))

# results as a list
lapply(cData, myfunc)

# results as a data frame
sapply(cData, myfunc)


sink()

Во всяком случае, я не знаю, может ли один из этих выходов быть тем, что вы ищете.

person juba    schedule 13.01.2010
comment
Мне нужен текстовый отчет, который можно распечатать и прикрепить к документации. Этот отчет должен содержать фрейм данных, исходный код и результаты, чтобы можно было проверить результаты вручную. lapply(cData,myfunc) будет работать, но если myfunc содержит какие-либо условия (for, if...), распечатка кода внутри for/if усекается, например: › myfunc ‹- function(v) { + n‹ -length(v) + if (n›5) + { + дисперсия ‹- var(v) + среднее ‹- среднее(v) + return(list(дисперсия=дисперсия,среднее=среднее)) + .... [ TRUNCATED] › # результатов в виде списка › lapply(cData, myfunc) $c1... Спасибо за помощь. - person Michael; 15.01.2010