Related
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()
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 :)
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
)
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.
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')