What I am trying to do is to make an animation ggplot having labels changing by the column names. So, my data is
EXTRACTION<-
structure(list(TICKERS = c("SPY", "IVV", "VTI"), X2020.11.02 = c(0,
0, 0), X2020.11.04 = c(-0.0110832443075151, -0.0258415332395525,
-0.028852983646287), X2020.11.08 = c(-0.00678564274087334, -0.028592196288115,
-0.0287979806647458), X2020.11.11...5 = c(0.00362433932387574,
-0.0183931126967061, -0.0159248566046306), X2020.11.11...6 = c(0.0475566216272374,
-0.0043522045803146, -0.00278232172594206), X2020.11.17 = c(0.0210585321899657,
-0.0175562162191414, -0.00540261044582935), X2020.11.19 = c(0.0574666424876265,
0.00762503019098637, 0.0215144350034273), X2020.11.24 = c(0.0327027084626714,
-0.00126684622955087, 0.00988617332076935), X2020.11.29 = c(0.0346871743474724,
-0.00331008153617796, 0.0140402133559614), X2020.12.07 = c(0.0264324000235459,
-0.00860290128787633, 0.00821403534252774), X2020.12.08...12 = c(0.0285459458362687,
-0.00675657470727886, 0.00932080453971507)), row.names = c("SPY",
"IVV", "VTI"), class = "data.frame")
This looks a bit messy so I will show how my data frame pretty much looks like
TICKERS X2020.11.02 X2020.11.03 X2020.11.04
SPY SPY -0.4461672 1.0571358 -0.3913777
IVV IVV -0.2668565 0.7148972 -0.2661292
VTI VTI 2.0241657 -0.6570240 -0.8967357
(I changed the rownames to use the data more easily. Actually there are hundreds of tickers for the real list but I'll omit the others for easy understandings.)
I have managed to make a code that works well for the ggplot animation.
CC <- sub(".", "", colnames(EXTRACTION))
a <- data.frame(ticker=c("SPY"), values=EXTRACTION[c("SPY"),c(2)], frame=rep(CC[2],3))
#trying to extract the data of SPY on the right date.
b <- data.frame(ticker=c("SPY"), values=EXTRACTION[c("SPY"),c(3)], frame=rep(CC[3],3))
c <- data.frame(ticker=c("SPY"), values=EXTRACTION[c("SPY"),c(4)], frame=rep(CC[4],3))
.....so on
data<-rbind(a,b,c)
library(gifski)
myPlot <- ggplot(data, aes(x=ticker,y=values, fill = ticker))+geom_bar(stat='identity')+theme_bw()+
transition_states(frame, transition_length = 6, state_length = 2)+ ease_aes('sine-in-out')+
labs(title = 'sector: {closest_state}')
animate(myPlot, duration = 5, fps = 20, width = 1000, height = 800, renderer = gifski_renderer())
so for the frame part, I have made a code CC in order to delete the first letter X in 'X2020.11.02'
Anyways, the code worked well but a user from stackoverflow told me once to "DON'T REPEAT YOURSELF" and the code seemed to be able to be looped. So I tried to make a code but it was too tough for me and did not work.
lapply(letters[1:3],function(x){x<-data.frame(ticker=c("SPY"),for(j in 2:4)
{values=EXTRACTION[c("SPY"),c(j)],frame=rep(CC[j],3))}})
what I was trying to do was list the alphabets a,b,c and cover them for function x. and in the same time with j in 2:4
, I wanted to match the a,b,c and 2,3,4.
So like
a<- .........,c(2).... rep(CC[2].....
b<- ........,c(3).... rep(CC[3].....
c<- .........,c(4).... rep(CC[4].....
How could I loop the codes? Thank you in advance.
The way you are using lapply
is not correct. Take a look at the documentation for lapply
lapply returns a list of the same length as X, each element of which is the result of applying FUN to the corresponding element of X.
There are some confusions you are making using lapply and in the function you are declaring inside lapply
.
But I think this is the kind of task that the functions in the tidyverse
package are perfect for (rearranging your dataset in a different format).
So I think it is more useful to show you how to do it with tidyverse
. Take a look at their tutorial. It will be very useful!
https://www.tidyverse.org/packages/
Using their functions you can accomplish what you want with few lines of code:
library(tidyverse)
data <- EXTRACTION %>%
# convert to long format
# this will take the data in all columns (except `TICKERS`) and "stack"" them vertically
# it will also create another column with the dates where each data came from
tidyr::pivot_longer(-TICKERS) %>%
# fix names of dates (remove 'X')
dplyr::mutate(name=gsub('X', '', name, fixed = TRUE)) %>%
# rename columns to match yours
dplyr::rename(ticker=TICKERS, values=value, frame=name)
myPlot <- ggplot(data, aes(x=ticker,y=values, fill = ticker)) +
geom_bar(stat='identity')+theme_bw()+
transition_states(frame, transition_length = 6, state_length = 2)+ ease_aes('sine-in-out')+
labs(title = 'sector: {closest_state}')
The most important function I used here was tidyr::pivot_longer
. Also, the %>%
operator is a "pipe operator". It gets what is on the left side and uses as argument in the function on the right side. So, x %>% f(y)
turns into f(x, y)
so you can use it to rewrite multiple operations.