Using character values as axis scale - r

I am working on graphing weekly order volumes in ggplot. I only get daily data and aggregate it like this:
subRC$week <- ISOweek(ymd(subRC$L01.Order.Date))
aggRC <- aggregate(subRC$Cases.Sold, by= list(subRC$week), sum)
L01.Order.Date is in MM-DD-YYYY format.
This works perfectly for me and my data looks like this (generated random values here but that doesn't change anything):
Group.1 x
2016-W01 15444
2016-W02 134900
2016-W03 2639
2016-W04 13055
2016-W05 18012
2016-W06 138764
2016-W07 73204
2016-W08 111646
2016-W09 33872
2016-W10 35456
2016-W11 106070
2016-W12 37843
2016-W13 66861
2016-W14 46273
2016-W15 19049
2016-W16 62065
2016-W17 52882
2016-W18 67134
2016-W19 60766
2016-W20 89763
2016-W21 80680
2016-W22 101619
2016-W23 120757
2016-W24 91560
2016-W25 123721
2016-W26 23647
2016-W27 67131
2016-W28 44775
2016-W29 123575
2016-W30 130845
2016-W31 114168
2016-W32 84923
2016-W33 123661
2016-W34 66065
2016-W35 80636
2016-W36 146880
2016-W37 50515
2016-W38 75468
2016-W39 145391
2016-W40 5586
2016-W41 16922
2016-W42 67943
2016-W43 140725
2016-W44 96454
2016-W45 47013
2016-W46 47276
2016-W47 54241
2016-W48 46889
2016-W49 116884
2016-W50 70194
2016-W51 141270
2016-W52 60754
2017-W01 5214
2017-W02 65803
2017-W03 48864
2017-W04 41300
2017-W05 65923
2017-W06 67856
2017-W07 104272
2017-W08 138575
2017-W09 97664
2017-W10 62303
2017-W11 78402
2017-W12 78170
2017-W13 27001
2017-W14 38086
2017-W15 87113
Now, I want to generate a plot where I want the axis scales to show the first, middle and end date. For the example here it would be: 2016-W01,2016-W34 and 2017-W15. The dates change during my analysis, so I want it to adjust to the dataset I am using. Here is what I have tried so far:
ggplot() +
geom_line(data = aggRC, aes(Group.1, x, group=1, color = "Retail Chubs"))+
scale_x_discrete(labels = c(min(aggRC$Group.1), median(aggRC$Group.1),
max(aggRC$Group.1)))
But that doesnt even do anything, I guess because Group.1 are characters and not numeric.
I have also tried to use scale_x_date, but that doesn't work since my date values are characters.
Maybe I need to use a different way to aggregate the orders? Let me know if you need me to add anything to my question. Would love any input on this and already appreciate your help. Already looked at similar questions but nothing really helped me with this.

Even with characters, you can select by position
This is a common problem and see some questions with many upvotes:
Select first and last row from grouped data and Filter the middle row of each group
Now combine both into one selection:
require(ggplot2)
require(dplyr)
p_dat <- example_df %>% #have renamed your dataframe and pre-filtered
arrange(Group.1) %>%
filter(row_number() %in% c(1, ceiling(n()/2), n()))
p_dat
Group.1 x
1 2016-W01 15444
2 2016-W34 66065
3 2017-W15 87113
ggplot() +
geom_point(data = p_dat, aes(x = Group.1, y = x ))
However, I would probably still advice to keep dates as dates and aggregate in a different manner, because this might make you more flexible for other questions
Of course, you should be able to filter by group with this approach too.

Related

Plot on statistics of data in r

I have a list of lists, where each list corresponds to a certain year, starting from 2005. I want a plot that looks like the one bellow where the distribution is shown and on the x-axis, it's the years (number of lists). In addition, it's showing the mean, 1sd and the histogram. I assume it would be done using ggplot but I wasn't able to figure it out. Note that the picture was taken from a simple google search and my data distribution is not going to look like this. This picture is only for concept reference.
Here's a subset of my list, with 3 lists within, for years 2005-2007.
dput(eig_inter_list[c(1,2,3)])
list(structure(c(0.314642768055768, 0.325549276750512, 0.32407558151974,
0.503037906331374, 0.177702652110427, 0.649874624573978, 0.22304809425227,
0.19744998358554, 0.322951763103893, 0.417206897701431, 0.378171649699382,
0.25116873932351, 0.485979263395877, 0.411851682123569, 1, 0.478943307151144,
0.710983939873711, 0.205890770051514, 0.335737092407451, 0.495130707288105,
0.395609776015166, 0.367388748844004, 0.236987996918897, 0.17727518450146,
0.542503233906977, 0.22322071021728, 0.305512801458551, 0.703463566780157,
0.0565731620746889, 0.281865665377428, 0.34675705775566, 0.240102820697777,
0.847955796670962, 0.467145199252136, 0.408110899113892, 0.121168347150886,
0.166279979571487, 0.225178903127632, 0.836003339903779, 0.298624839828843,
0.156832369183448, 0.331724029229045, 0.28607359410209, 0.438251331553188,
0.531970745173967, 0.473559658632999, 0.339927590064139, 0.329554185654697,
0.23010077174135, 0.444399306655095, 0.265064970418036, 0.54141477127972,
0.181034728719507, 0.217971681487819, 0.702604336646787, 0.260277784525433,
0.9313793258404), .Dim = c(57L, 1L)), structure(c(0.758053727134031,
0.389169917077854, 0.553155900977713, 0.680957693695371, 0.688478238016961,
0.5406614343729, 0.654085903776063, 0.249245017029272, 0.527924916117291,
0.607686315557293, 0.328402935290058, 0.472653172631753, 0.503447923078263,
0.540956133924371, 0.367957509649887, 0.537869789262281, 0.177185397396901,
0.49323257867289, 0.380042131111929, 0.76085241271694, 0.540174821432495,
0.283063101888133, 0.319997654939547, 0.651366853994039, 0.706918785162937,
0.578280317866076, 0.871853266130338, 0.874076858150783, 1, 0.611669207162514,
0.28036164071929, 0.292694661837052, 0.610126478002428, 0.380386438921713,
0.669982812090512, 0.122065848180652, 0.974400986291088, 0.945135694392546,
0.462456530300744, 0.134501132230783, 0.322784038090134, 0.317780702999941,
0.662847059747895, 0.523285813371882, 0.668825630786058, 0.79637143229052,
0.379229953581731, 0.282559418794954, 0.745322058370275, 0.697765403065504,
0.282171232377215, 0.672824204974444, 0.812732702343435, 0.747236048953355,
0.810360825374334, 0.147736041262474, 0.638551018944304), .Dim = c(57L,
1L)), structure(c(0.580650487050986, 0.226493031789664, 0.216153469107205,
0.679582322890881, 0.585765696317977, 0.277602052620714, 0.301697850942933,
0.539494048925467, 0.22052504674914, 0.279450501649262, 0.292210734005604,
0.406706750636561, 0.253178327897084, 0.26902431345799, 0.72080329402394,
0.538483400997092, 0.132513153071638, 0.169267787671607, 0.355070307460915,
0.420987061713029, 0.355905556319682, 0.423354094728718, 0.225064747308464,
0.368813823547299, 0.290838727568061, 0.191959913771819, 0.412085260195494,
0.220140351021593, 0.251950925564949, 0.360732509927935, 0.130353223587661,
0.355856853738614, 0.399558273021718, 0.351244298106977, 0.280432050072677,
0.51121978973842, 0.300682631494935, 0.39923136729231, 0.217749058297645,
0.347719424129099, 0.28916475155952, 0.531747942212439, 0.384583756749702,
0.19911455191363, 0.574044809883757, 0.206919558647874, 1, 0.327370421244658,
0.561049901898945, 0.177575568867026, 0.311627824832627, 0.214432911950344,
0.405893310593152, 0.328365875498285, 0.403268555194588, 0.21904514354561,
0.243848932866513), .Dim = c(57L, 1L)))
Update:
Adding #Dan Adams suggestion (see comments):
map_df(df_list, ~as.data.frame(.x), .id="id") %>%
ggplot(aes(x=id, y=V1, fill=id)) +
geom_violindot(stackratio = 0.7) +
stat_summary()+
theme_modern()
First answer:
What you need is a Half-violin Half-dot plot: https://easystats.github.io/see/reference/geom_violindot.html
You can use see package with geom_violindot() function after preparing your list of lists, like here:
library(ggplot2)
library(purrr)
library(see)
# ad names to your lists in your list called df_list
names(df_list) <- c("df1", "df2", "df3")
# add a new column to each list with the list name and then use ggplot to plot
map_df(df_list, ~as.data.frame(.x), .id="id") %>%
ggplot(aes(x=id, y=V1, fill=id)) +
geom_violindot() +
theme_modern()

ggplot2 - Barchart ot Histogram in R - plotting more than one variable

So sorry I'm quite new to R and have been trying to do this by myself but have been struggling.
I'm trying to do some sort of barplot or histogram of the tag 'Amateur' over the years 2007 to 2013 to show how it's changed over time.
The data set was downloaded from: https://sexualitics.github.io/ specifically looking at the hamster.csv
Here is some of the initial preprocessing of the data below.
head(xhamster) # Need to change upload_date into a date column, then add new column containing year
xhamster$upload_date<-as.Date(xhamster$upload_date,format="%d/%m/%Y")
xhamster$Year<-year(ymd(xhamster$upload_date)) #Adds new column containing just the year
xhamster$Year<-as.integer(xhamster$Year) # Changing new Year variable into an interger
head(xhamster) # Check changes made correctly
The filter for the years:
Yr2007<-xhamster%>%
filter_at(vars(Year),any_vars(.%in%c("2007")))
Yr2008<-xhamster%>%
filter_at(vars(Year),any_vars(.%in%c("2008")))
Yr2009<-xhamster%>%
filter_at(vars(Year),any_vars(.%in%c("2009")))
Yr2010<-xhamster%>%
filter_at(vars(Year),any_vars(.%in%c("2010")))
Yr2011<-xhamster%>%
filter_at(vars(Year),any_vars(.%in%c("2011")))
Yr2012<-xhamster%>%
filter_at(vars(Year),any_vars(.%in%c("2012")))
Yr2013<-xhamster%>%
filter_at(vars(Year),any_vars(.%in%c("2013")))
For example, I want to create a plot for the tag 'Amateur' in the data. Here is some of the code I have already done:
Amateur<-grep("Amateur",xhamster$channels)
Amateur_2007<-grep("Amateur", Yr2007$channels)
Amateur_2008<-grep("Amateur", Yr2008$channels)
Amateur_2009<-grep("Amateur", Yr2009$channels)
Amateur_2010<-grep("Amateur", Yr2010$channels)
Amateur_2011<-grep("Amateur", Yr2011$channels)
Amateur_2012<-grep("Amateur", Yr2012$channels)
Amateur_2013<-grep("Amateur", Yr2013$channels)
Amateur_2007 <- length(Amateur_2007)
Amateur_2008 <- length(Amateur_2008)
Amateur_2009 <- length(Amateur_2009)
Amateur_2010 <- length(Amateur_2010)
Amateur_2011 <- length(Amateur_2011)
Amateur_2012 <- length(Amateur_2012)
Amateur_2013 <- length(Amateur_2013)
Plot:
Amateur <- cbind(Amateur_2007, Amateur_2008, Amateur_2009,Amateur_2010, Amateur_2011, Amateur_2012, Amateur_2013)
barplot((Amateur),beside=TRUE,col = c("red","orange"),ylim=c(0,90000))
title(main="Usage of 'Amateur' as a tag from 2007 to 2013")
title(xlab="Amateur")
title(ylab="Frequency")
Plot showing amateur tag over the years
However this isn't exactly a great plot. I'm looking for a way to plot using ggplot ideally and to have the names of each bar to be the year rather than 'Amateur_2010' etc. How do I do this?
An even better bonus if I can add 'nb_views' for each year with this tag usage or something like that.
There are lots of ways to approach this, here is how I would tackle it:
library(tidyverse)
library(lubridate)
library(vroom)
xhamster <- vroom("xhamster.csv")
xhamster$upload_date<-as.Date(xhamster$upload_date,format="%d/%m/%Y")
xhamster$Year <- year(ymd(xhamster$upload_date))
xhamster %>%
filter(Year %in% 2007:2013) %>%
filter(grepl("Amateur", channels)) %>%
ggplot(aes(x = Year, y = ..count..)) +
geom_bar() +
scale_x_continuous(breaks = c(2007:2013),
labels = c(2007:2013)) +
ylab(label = "Count") +
xlab(label = "Amateur") +
labs(title = "Usage of 'Amateur' as a tag from 2007 to 2013",
caption = "Data obtained from https://sexualitics.github.io/ under a CC BY-NC-SA 3.0 license") +
theme_minimal(base_size = 14)
As Jared said, there are lots of ways, but I want to solve it with your way, so that you can internalize the solution better.
I just changed your cbind in the plot:
Amateur <- cbind("2007" = Amateur_2007,"2008" = Amateur_2008,"2009" = Amateur_2009, "2010" =Amateur_2010, "2011" = Amateur_2011, "2012" = Amateur_2012, "2013" = Amateur_2013)
As you can see, you can give names to your columns into cbind function like that :)

How to manipulate plots in spplot in R

I am trying to use spplot to visualize plots from different months. I'd like to change this figure so the same months are in the same columns to easily compare. I would like to push May 2016 5 panels in, so all the rest of the months are in line. I hope this makes sense.
click here for figure
I have missing data for Dec2017 for now which is why it's blacked out.
Here is my code:
stack_months <- stack(May2016, June2016, July2016, Aug2016, Sep2016, Oct2016, Nov2016, Dec2016, January2017, Febuary2017, March2017, April2017, May2017, June2017, July2017, July2017, Aug2017, Sep2017, Oct2017, Nov2017, Dec2017, January2018, Febuary2018, March2017, April2018, May2018, June2017, July2017, July2018, Aug2018, Sep2018, Oct2018, Nov2018, Dec2018, January2019, Febuary2019, March2019, April2019, May2019, June2019, July2019, July2019)
spplot(stack_months, col.regions=viridis(20), names.attr = c("May2016", "June2016", "July2016", "Aug2016", "Sep2016", "Oct2016", "Nov2016", "Dec2016",
"Jan2017", "Feb2017", "March2017", "April2017", "May2017", "June2017", "July2017", "July2017", "Aug2017", "Sep2017", "Oct2017", "Nov2017", "Dec2017",
"Jan2018", "Feb2018", "March2017", "April2018", "May2018", "June2017", "July2017", "July2018", "Aug2018", "Sep2018", "Oct2018", "Nov2018", "Dec2018",
"Jan2019", "Feb2019", "March2019", "April2019", "May2019", "June2019", "July2019", "July2019"), layout = c(12,4))
Is there an easy way to manipulate the panels?
Note that you have type some of the months twice, for example July2017 appeared 3 times and March2017, 2 times, June2017 2x and July2019 2x.
What I have below are complete months from May2016 to July2019, so that when you plot, the months will align.
library(raster)
library(sp)
library(viridis)
library(lattice)
months=c("May2016", "June2016", "July2016", "Aug2016", "Sep2016", "Oct2016",
"Nov2016", "Dec2016", "Jan2017", "Feb2017", "March2017", "April2017",
"May2017", "June2017", "July2017","Aug2017", "Sep2017",
"Oct2017", "Nov2017", "Dec2017","Jan2018", "Feb2018", "March2018",
"April2018", "May2018", "Jun2018", "July2018", "Aug2018",
"Sep2018", "Oct2018", "Nov2018", "Dec2018","Jan2019", "Feb2019",
"March2019", "April2019", "May2019", "June2019", "July2019")
I don't have your data, so I simulate something for the image:
r <- raster(system.file("external/test.grd", package="raster"))
stack_months = do.call(stack,lapply(months,function(i)runif(1)*r))
You defined layout to be 12,4 so you will have 48 entries which are filled by row. In your case, the first 4 will not be plotted and the last 5 will not be plotted:
SKIP = rep(FALSE,12*4)
SKIP[1:4] = TRUE
SKIP[44:48] = TRUE
Then we plot using the SKIP above:
spplot(stack_months, col.regions=viridis(20),
layout = c(12,4),
strip = strip.custom(par.strip.text = list(cex = 0.65)),
names.attr = months,
skip=SKIP
)

Multiple Histograms On 1 page (without making long data)

I want to make a histogram for each column. Each Column has three values (Phase_1_Mean, Phase_2_Mean and Phase_3_Mean)
The output should be:
12 histograms (because we have 12 rows), and per histogram the 3 values showed in a bar (Y axis = value, X axis = Phase_1_Mean, Phase_2_Mean and Phase_3_Mean).
Stuck: When I search the internet, almost everyone is making a "long" data frame. That is not helpful with this example (because than we will generate a value "value". But I want to keep the three "rows" separated.
At the bottom you can find my data. Appreciated!
I tried this (How do I generate a histogram for each column of my table?), but here is the "long table" problem, after that I tried Multiple Plots on 1 page in R, that solved how we can plot multiple graphs on 1 page.
dput(Plots1)
structure(list(`0-0.5` = c(26.952381, 5.455598, 28.32947), `0.5-1` =
c(29.798635,
25.972696, 32.87372), `1-1.5` = c(32.922764, 41.95935, 41.73577
), `1.5-2` = c(31.844156, 69.883117, 52.25974), `2-2.5` = c(52.931034,
128.672414, 55.65517), `2.5-3` = c(40.7, 110.1, 63.1), `3-3.5` =
c(73.466667,
199.533333, 70.93333), `3.5-4` = c(38.428571, 258.571429, 95),
`4-4.5` = c(47.6, 166.5, 233.4), `4.5- 5` = c(60.846154,
371.730769, 74.61538), `5-5.5` = c(7.333333, 499.833333,
51), `5.5-6` = c(51.6, 325.4, 82.4), `6-6.5` = c(69, 411.5,
134)), class = "data.frame", .Names = c("0-0.5", "0.5-1",
"1-1.5", "1.5-2", "2-2.5", "2.5-3", "3-3.5", "3.5-4", "4-4.5",
"4.5- 5", "5-5.5", "5.5-6", "6-6.5"), row.names = c("Phase_1_Mean",
"Phase_2_Mean", "Phase_3_Mean"))
Something which is showed in this example (which didn't worked for me, because it is Python) https://www.google.com/search?rlz=1C1GCEA_enNL765NL765&biw=1366&bih=626&tbm=isch&sa=1&ei=Yqc8XOjMLZDUwQLp9KuYCA&q=multiple+histograms+r&oq=multiple+histograms+r&gs_l=img.3..0i19.4028.7585..7742...1.0..1.412.3355.0j19j1j0j1......0....1..gws-wiz-img.......0j0i67j0i30j0i5i30i19j0i8i30i19j0i5i30j0i8i30j0i30i19.j-1kDXNKZhI#imgrc=L0Lvbn1rplYaEM:
I think you have to reshape to long to make this work, but I don't see why this is a problem. I think this code achieves what you want. Note that there are 13 plots because you have 13 (not 12) columns in the dataframe you posted.
# Load libraries
library(reshape2)
library(ggplot2)
Plots1$ID <- rownames(Plots1) # Add an ID variable
Plots2 <- melt(Plots1) # melt to long format
ggplot(Plots2, aes(y = value, x = ID)) + geom_bar(stat = "identity") + facet_wrap(~variable)
Below is the resulting plot. I've kept it basic, but of course you can make it pretty by adding further layers.

Stacked Area Histogram in R

I ran a Pig job on a Hadoop cluster that crunched a bunch of data down into something R can handle to do a cohort analysis. I have the following script, and as of the second to last line I have the data in the format:
> names(data)
[1] "VisitWeek" "ThingAge" "MyMetric"
VisitWeek is a Date. ThingAge and MyMetric are integers.
The data looks like:
2010-02-07 49 12345
The script I have so far is:
# Load ggplot2 for charting
library(ggplot2);
# Our file has headers - column names
data = read.table('weekly_cohorts.tsv',header=TRUE,sep="\t");
# Print the names
names(data)
# Convert to dates
data$VisitWeek = as.Date(data$VisitWeek)
data$ThingCreation = as.Date(data$ThingCreation)
# Fill in the age column
data$ThingAge = as.integer(data$VisitWeek - data$ThingCreation)
# Filter data to thing ages lt 10 weeks (70 days) + a sanity check for gt 0, and drop the creation week column
data = subset(data, data$ThingAge <= 70, c("VisitWeek","ThingAge","MyMetric"))
data = subset(data, data$ThingAge >= 0)
print(ggplot(data, aes(x=VisitWeek, y=MyMetric, fill=ThingAge)) + geom_area())
This last line does not work. I've tried lots of variations, bars, histograms, but as usual R docs defeat me.
I want it to show a standard Excel style stacked area chart - one time series for each ThingAge stacked across the weeks in the x axis, with the date on the y axis. An example of this kind of chart is here: http://upload.wikimedia.org/wikipedia/commons/a/a1/Mk_Zuwanderer.png
I've read the docs here: http://had.co.nz/ggplot2/geom_area.html and http://had.co.nz/ggplot2/geom_histogram.html and this blog http://chartsgraphs.wordpress.com/2008/10/05/r-lattice-plot-beats-excel-stacked-area-trend-chart/ but I can't quite make it work for me.
How can I achieve this?
library(ggplot2)
set.seed(134)
df <- data.frame(
VisitWeek = rep(as.Date(seq(Sys.time(),length.out=5, by="1 day")),3),
ThingAge = rep(1:3, each=5),
MyMetric = sample(100, 15))
ggplot(df, aes(x=VisitWeek, y=MyMetric)) +
geom_area(aes(fill=factor(ThingAge)))
gives me the image below. I suspect your problem lies in correctly specifying the fill mapping for the area plot: fill=factor(ThingAge)
ggplot(data.set, aes(x = Time, y = Value, colour = Type)) +
geom_area(aes(fill = Type), position = 'stack')
you need to give the geom_area a fill element and also stack it (though that might be a default)
found here http://www.mail-archive.com/r-help#r-project.org/msg84857.html
I was able to get my result with this:
I loaded the stackedPlot() function from https://stat.ethz.ch/pipermail/r-help/2005-August/077475.html
The function (not mine, see link) was:
stackedPlot = function(data, time=NULL, col=1:length(data), ...) {
if (is.null(time))
time = 1:length(data[[1]]);
plot(0,0
, xlim = range(time)
, ylim = c(0,max(rowSums(data)))
, t="n"
, ...
);
for (i in length(data):1) {
# Die Summe bis zu aktuellen Spalte
prep.data = rowSums(data[1:i]);
# Das Polygon muss seinen ersten und letzten Punkt auf der Nulllinie haben
prep.y = c(0
, prep.data
, 0
)
prep.x = c(time[1]
, time
, time[length(time)]
)
polygon(prep.x, prep.y
, col=col[i]
, border = NA
);
}
}
Then I reshaped my data to wide format. Then it worked!
wide = reshape(data, idvar="ThingAge", timevar="VisitWeek", direction="wide");
stackedPlot(wide);
Turning integers into factors and using geom_bar rather than geom_area worked for me:
df<-expand.grid(x=1:10,y=1:6)
df<-cbind(df,val=runif(60))
df$fx<-factor(df$x)
df$fy<-factor(df$y)
qplot(fy,val,fill=fx,data=df,geom='bar')

Resources