Reputation: 603
I want to make function that loops through a dataframe to plots different plot figures next to each using par(), one plot is bar plot, second is scatter plot and the last is box plot, my data frame:
structure(list(rated = c(FALSE, TRUE, TRUE, TRUE), turns = c(13L,
16L, 61L, 61L), victory_status = structure(c(2L, 3L, 1L, 1L), .Label = c("mate",
"outoftime", "resign"), class = "factor"), winner = structure(c(2L,
1L, 2L, 2L), .Label = c("charcoal", "cream"), class = "factor"),
increment_code = structure(c(1L, 3L, 3L, 2L), .Label = c("15+2",
"20+0", "5+10"), class = "factor"), cream_rating = c(1500L,
1322L, 1496L, 1439L), charcoal_rating = c(1191L, 1261L, 1500L,
1454L), opening_name = structure(c(4L, 2L, 1L, 3L), .Label = c("King's Pawn Game: Leonardis Variation",
"Nimzowitsch Defense: Kennedy Variation", "Queen's Pawn Game: Zukertort Variation",
"Slav Defense: Exchange Variation"), class = "factor")), row.names = c(NA,
4L), class = "data.frame")
I tried:
par(mai=rep(0.5, 4))
layout(matrix(c(1,1, 2,2, 0, 3,3, 0), ncol = 4, byrow = TRUE))
chess_games<-read.csv("./data/games.csv")
chess_games_rated<-table(chess_games$rated)
head (chess_games_rated)
barplot(chess_games_rated, cex.lab=1.5, cex.axis=1.2, font=1)
chess_games<-read.csv("./data/games.csv")
chess_games_rated<-table(chess_games$winner, chess_games$rated)
barplot(chess_games_rated, col=c("blue","red","green"), cex.axis=1.5)
legend(x="topleft", legend = levels(chess_games$winner), col=c("blue","red","green"), pch=19, cex=1, pt.cex = 1)
boxplot.1<-boxplot(cream_rating ~ victory_status, chess_games[!chess_games$winner %in% "draw", ], cex.axis=1.2)
Can I assign the above code into a function?
Upvotes: 0
Views: 91
Reputation: 160817
A literal translation of your three manual plots into a function looks like below.
myfunc <- function(data) {
stopifnot(
all(c("rated", "winner", "cream_rating", "victory_status") %in% names(data))
)
layout(matrix(c(1,1, 2,2, 0, 3,3, 0), ncol = 4, byrow = TRUE))
rated <- xtabs(~ rated, data = data)
br1 <- barplot(rated, cex.lab = 1.5, cex.axis = 1.2, font = 1)
winner_rated <- xtabs(~ winner + rated, data = data)
br2 <- barplot(winner_rated, col = c("blue","red","green"), cex.axis = 1.5)
legend(x = "topleft", legend = levels(data$winner),
col = c("blue","red","green"), pch = 19, cex = 1, pt.cex = 1)
bx3 <- boxplot(cream_rating ~ victory_status, data = data[!data$winner %in% "draw", ],
cex.axis = 1.2)
invisible(list(br1, br2, bx3))
}
myfunc(chess_games)
It does not check that data$winner
is a factor
, nor if the number of unique levels
is other than length 3.
It does invisibly return a list
with the return value of each of the three plots. While it seems uninspiring for the barplot
s, it is still somewhat informative if you want/need it elsewhere. The boxplot
contains significantly more information if you need it.
ret <- myfunc(chess_games)
str(ret)
# List of 3
# $ : num [1:2, 1] 0.7 1.9
# $ : num [1:2] 0.7 1.9
# $ :List of 6
# ..$ stats: 'integer' num [1:5, 1:4] NA NA NA NA NA ...
# ..$ n : num [1:4] 0 3 1 1
# ..$ conf : num [1:2, 1:4] NA NA 1458 1534 1500 ...
# ..$ out : num(0)
# ..$ group: num(0)
# ..$ names: chr [1:4] "draw" "mate" "outoftime" "resign"
It is not general, in that it won't work with customizations or slightly-different data. Doing so would be rather difficult, since you're using different customization for each plot. Because of this, I start with stopifnot
which will complain (and fail) if all of the required columns are not found.
If you need this to be more dynamic (variable number of plots or different variables to run table
(or xtabs
) on, then this is certainly feasible but you will need to lose per-plot customization.
Data. I removed the last column since you weren't using it and it was not parsing with this simple read.table
.
chess_games <- read.table(header = TRUE, stringsAsFactors = TRUE, text="
rated turns victory_status winner increment_code cream_rating charcoal_rating
FALSE 13 outoftime cream 15+2 1500 1191
TRUE 16 resign charcoal 5+10 1322 1261
TRUE 61 mate cream 5+10 1496 1500
TRUE 61 mate cream 20+0 1439 1454
TRUE 95 mate cream 30+3 1523 1469
FALSE 5 draw draw 10+0 1250 1002 ")
Upvotes: 1