Jeremy
Jeremy

Reputation: 876

save the outputs from print statement in a data.frame in R

Is it possible to save outputs from "print" statements as a data.frame in R? The example code is:

for (i in 1:3){
  print(paste(i,i+1,i+2))
}

Then I want to store the numbers in the red circle into a clean 3x3 data.frame. Thanks.

enter image description here

Upvotes: 0

Views: 1487

Answers (1)

Len Greski
Len Greski

Reputation: 10875

Print isn't necessary.

x <- 1:3
y <- x + 1
z <- y + 1

data <- data.frame(x,y,z)
data

...and the output:

> data
  x y z
1 1 2 3
2 2 3 4
3 3 4 5
> 

Saving results of print() to a vector

The results of a series of print() functions can be saved to a vector as follows.

x <- 1:3
printouts <- unlist(lapply(x,function(i) print(paste(i,i+1,i+2))))
printouts

...and the output:

> printouts
[1] "1 2 3" "2 3 4" "3 4 5"
> 

Converting the vector to a data frame

We can take the vector and convert to a data frame by reading with read.csv(). First, we'll edit the print a bit so it separates the data with commas rather than spaces. Then we'll generate the printouts and read into a data frame.

x <- 1:3
# use comma so we can parse with read.csv
printouts <- unlist(lapply(x,function(i) print(paste(i,i+1,i+2,sep=","))))
diagnostics <- read.csv(text = printouts,header = FALSE)
diagnostics

...and the output:

> diagnostics
  V1 V2 V3
1  1  2  3
2  2  3  4
3  3  4  5
> 

Note that more useful column names can be set by using the col.names= argument in read.csv().

A reproducible example using multiple input files

Based on comments to my answer, here is a reproducible example that reads data from the Pokémon Stats database, where we've separated the Pokémon into files by generation (1 - 7).

We'll read the data and write out to a log file any Pokémon whose Attack stats are greater than 120. First, we have code to download the zip file from my GitHub site if it hasn't already been downloaded.

if(!dir.exists("./pokemonData")){
     # download and unzip 
     download.file("https://raw.githubusercontent.com/lgreski/pokemonData/master/pokemonData.zip",
                   "pokemonData.zip",
                   mode="wb")
     unzip("pokemonData.zip")
}

Next, we'll set up a log file, including overwriting any prior copies so we can use cat() with append=TRUE as we write to the log file.

logFile <- "./pokemonData/highAttackStat.log"
# erase file in case it already exists, because we'll cat() with append mode
if (file.exists(logFile)) file.remove(logFile)

Next, we'll read the files and write to the log any observations where the Attack stat is greater than 120.

# read files and write to log any obs with 

thePokemonFiles <- list.files("./pokemonData",
                              full.names=TRUE)

dataList <- lapply(thePokemonFiles,function(x) {
     # read data 
     data <- read.csv(x)
     # write data for Pokemon with Attack > 120
     subset <- data[data$Attack > 120,]
     for(i in 1:nrow(subset)){
          if(subset[i,"Attack"] > 120){
               cat(paste(x,subset[i,"Number"],subset[i,"Name"],subset[i,"Attack"],sep=","),
                   file=logFile,sep="\n",append=TRUE)
          }
     }
})

Finally, we create a data frame from the log file via read.csv().

# at this point we can read logfile w/ read.csv
theSubset <- read.csv(logFile,header = FALSE,col.names = c("File","Number","Name","Attack"))
head(theSubset)

...and the output:

> head(theSubset)
                     File Number                      Name Attack
1 ./pokemonData/gen01.csv      6 CharizardMega Charizard X    130
2 ./pokemonData/gen01.csv     15     BeedrillMega Beedrill    150
3 ./pokemonData/gen01.csv     68                   Machamp    130
4 ./pokemonData/gen01.csv     99                   Kingler    130
5 ./pokemonData/gen01.csv    112                    Rhydon    130
6 ./pokemonData/gen01.csv    115 KangaskhanMega Kangaskhan    125
> 

Upvotes: 2

Related Questions