Recursively plot multiple tables and outputs to images in R - r

Hi I have multiple tables, let say 20 tables, to be plotted and outputted to jpeg images as below.
table1:
list percentage
1 20
2 50
3 30
...
table2:
list percentage
1 40
2 10
3 20
...
I wish to do a for loop to recursively plot each table and output to a jpeg image. I tried the code below:
for (i in 1:20) {
jpeg(paste0("plot_",i,".jpg"))
plot(paste0("table",i, "$percentage"))
dev.off()
}
It showed error. I wonder how I can write to get it worked. Thanks in advance.

Passing a string to plot is probably what is causing you problems. Use eval:
for (i in 1:20) {
jpeg(paste0("plot_",i,".jpg"))
plot(eval(parse(text=paste0("table",i, "$percentage"))))
dev.off()
}

Related

Why is R adding empty factors to my data?

I have a simple data set in R -- 2 conditions called "COND", and within those conditions adults chose between one of 2 pictures, we call house or car. This variable is called "SAW"
I have 69 people, and 69 rows of data
FOR SOME Reason -- R is adding an empty factor to both, How do I get rid of it?
When I type table to see how many are in each-- this is the output
table(MazeData$SAW)
car house
2 9 59
table(MazeData$COND)
Apples No_Apples
2 35 33
Where the heck are these 2 mystery rows coming from? it wont let me make my simple box plots and bar plots or run t.test because of this error - can someone help? thanks!!

Trying to make a graph with multiple lines using ggplot

I am new to R and I have been trying to make a line graph with mupltiple lines. I have tried the 'plot' function but didn't get the desired result so I am now trying the ggplot.
I keep running into error:
Aesthetics must be either length 1 or the same as the data (100): x
and there's obviously no graph output.
Any help is much appreciated
I have rearranged my data, before it had 4 separate columns for different consumer types but now I have merged them and made a column that identifies each consumer.
This is the part of the code that generates the error
ggplot(data=consumers,aes(x=scenarios,y=unitary.bill)) +
geom_line(aes(color=consumer.type,group=consumer.type))
my data looks like this:
scenario unitary.bill consumer.type
1 1 0.076536835 net.cons
2 2 0.075835361 net.cons
3 3 0.076696548 net.cons
4 4 0.076431602 net.cons
5 5 0.076816135 net.cons
.........
27 2 0.076794287 smart.cons
28 3 0.075555555 smart.cons
29 4 0.077126955 smart.cons
30 5 0.077925161 smart.cons
.......
100 25 0.049247761 smart.pros
I expect the a line graph to have four different colors (each representing my consumer type) and the scenarios at the x-axis.
Thanks for all the help from Camille and Infominer. My code now looks like this (I added some more details)
ggplot(data=consumers,aes(x = scenarios,y = unitary.bill, colour= SMCs)) +
geom_line(size=1) + scale_colour_manual(values=c("indianred1", "yellowgreen","lightpink","springgreen4"))+
ggtitle(" Unitary bill for each SMC type at the end of the scenario runs")+
scale_x_continuous(breaks=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25))
and the graph looks as I wanted it to. However, if I could put some more distance between the title and the graph that will make it prettier.
you can view the graph here

R - Function that call conditionally another functions

I am working with igraph package and I'm trying to build a function that calculates the number of intra-community edges of different algorithm implementation. I try to concatenate everything inside the function even the algorithms community detection functions. Like this:
library("igraph")
intra.edges<-function(G,algorithm) {
if(algorithm==1){
Mod<-cluster_louvain(G)}
if(algoritmo==2){
Mod<-cluster_edge_betweenness(G)}
if(algoritmo==3){
Mod<-cluster_walktrap(G)}
Com<-as.data.frame(sizes(Mod))
NoCom<-as.vector(Com$Community.sizes)
vert<-NULL
for(i in 1:length(NoCom)){
M<-which(membership(Mod)==i)
sg<-induced.subgraph(G,M)
c.ec<-ecount(sg)
vert<-c.ec
}
intra<-data.frame(Com,vert)
print(intra)
}
When I try the function, it don't works correctly. For example:
When I run:
G <- graph.famous("Zachary")
intra.edges(G,1)
I get:
Community.sizes Freq vert
1 9 6
2 7 6
3 9 6
4 4 6
5 5 6
And when I run intra.edges(G,2) or intra.edges(G,3) I get the same output.
Also, not all the network's components have six vertex, it is only in one component.
You can either add your calculated value of vert to the dataframe with each iteration of your for loop by changing your code to:
intra<-Com
for(i in 1:length(NoCom)){
M<-which(membership(Mod)==i)
sg<-induced.subgraph(G,M)
intra$vert[i]<-ecount(sg)
}
print(intra)
Or, as #dash2 suggested, create a vector called vert and add values sequentially like this:
vert<-NULL
for(i in 1:length(NoCom)){
M<-which(membership(Mod)==i)
sg<-induced.subgraph(G,M)
c.ec<-ecount(sg)
vert[i]<-c.ec
}

Process list of histograms into separate histograms - R

I have a list of data frames which look like this
F0001
PoseID Score
1 AAAA_1 -13.70
2 AAAA_2 -9.21
3 AAAA_3 -7.60
4 AAAA_4 -6.28
F0002
PoseID Score
1 AAAB_1 -14.90
2 AAAB_2 -13.92
3 AAAB_3 -13.49
And essentially I'd like to generate plots for each data frame's $Score and spit them out as images.
One of the ways I've tried was to import all the data frames into a list.
lst <- mget(ls(pattern='^F\\d+'))
then run the hist() on each separate data frame in the list and push that out into a list of histograms.
hist <- lapply(lst, function(x) hist(x$Score))
The idea would then be to spit out that list as separate histograms saved to files. Seems like a simple thing but it's beating me at the moment. Any R boffins have a good way to do this? Maybe other approaches (e.g. for-loop on each separate data frame rather than adding it to a list and performing operations on it)?
The following saves each file with the name image1, image2,... as a pdf file in your working directory. You can also change pdf to jpeg or png or ps.
lapply(1:2,function(i){
pdf(paste0("image",i,".pdf"))
hist(mtcars[,i])
dev.off()})

R Refer to (part of) data frame using string in R

I have a large data set in which I have to search for specific codes depending on what i want. For example, chemotherapy is coded by ~40 codes, that can appear in any of 40 columns called (diag1, diag2, etc).
I am in the process of writing a function that produces plots depending on what I want to show. I thought it would be good to specify what I want to plot in a input data frame. Thus, for example, in case I only want to plot chemotherapy events for patients, I would have a data frame like this:
Dataframe name: Style
Name SearchIn codes PlotAs PlotColour
Chemo data[substr(names(data),1,4)=="diag"] 1,2,3,4,5,6 | red
I already have a function that searches for codes in specific parts of the data frame and flags the events of interest. What i cannot do, and need your help with, is referring to a data frame (Style$SearchIn[1]) using codes in a data frame as above.
> Style$SearchIn[1]
[1] data[substr(names(data),1,4)=="diag"]
Levels: data[substr(names(data),1,4)=="diag"]
I thought perhaps get() would work, but I cant get it to work:
> get(Style$SearchIn[1])
Error in get(vars$SearchIn[1]) : invalid first argument
enter code here
or
> get(as.character(Style$SearchIn[1]))
Error in get(as.character(Style$SearchIn[1])) :
object 'data[substr(names(data),1,5)=="TDIAG"]' not found
Obviously, running data[substr(names(data),1,5)=="TDIAG"] works.
Example:
library(survival)
ex <- data.frame(SearchIn="lung[substr(names(lung),1,2) == 'ph']")
lung[substr(names(lung),1,2) == 'ph'] #works
get(ex$SearchIn[1]) # does not work
It is not a good idea to store R code in strings and then try to eval them when needed; there are nearly always better solutions for dynamic logic, such as lambdas.
I would recommend using a list to store the plot specification, rather than a data.frame. This would allow you to include a function as one of the list's components which could take the input data and return a subset of it for plotting.
For example:
library(survival);
plotFromSpec <- function(data,spec) {
filteredData <- spec$filter(data);
## ... draw a plot from filteredData and other stuff in spec ...
};
spec <- list(
Name='Chemo',
filter=function(data) data[,substr(names(data),1,2)=='ph'],
Codes=c(1,2,3,4,5,6),
PlotAs='|',
PlotColour='red'
);
plotFromSpec(lung,spec);
If you want to store multiple specifications, you could create a list of lists.
Have you tried using quote()
I'm not entirely sure what you want but maybe you could store the things you're trying to get() like
quote(data[substr(names(data),1,4)=="diag"])
and then use eval()
eval(quote(data[substr(names(data),1,4)=="diag"]), list(data=data))
For example,
dat <- data.frame("diag1"=1:10, "diag2"=1:10, "other"=1:10)
Style <- list(SearchIn=c(quote(data[substr(names(data),1,4)=="diag"]), quote("Other stuff")))
> head(eval(Style$SearchIn[[1]], list(data=dat)))
diag1 diag2
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6

Resources