使用 'for loop' 和列表的 R 动画 ggplot

R animation ggplot using 'for loop' and listing

我想做的是制作一个动画 ggplot,其标签随列名变化。所以,我的数据是

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")

这看起来有点乱,所以我将展示我的数据框的大致样子

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

(我更改了行名以更轻松地使用数据。 实际上,真正的列表有数百个代码,但为了便于理解,我将省略其他代码。)

我已经成功编写了一个适用于 ggplot 动画的代码。

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())

所以对于框架部分,我做了一个代码CC,以便删除'X2020.11.02'

中的第一个字母X

无论如何,该代码运行良好,但 Whosebug 的一位用户曾经告诉我“不要重复自己”,代码似乎可以循环。所以我试着做了一个代码,但对我来说太难了,没有成功。

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))}})

我想做的是列出字母 a、b、c 并为函数 x 覆盖它们。在使用 j in 2:4 的同时,我想匹配 a、b、c 和 2、3、4。

很喜欢

a<- .........,c(2).... rep(CC[2].....
b<- ........,c(3).... rep(CC[3].....
c<- .........,c(4).... rep(CC[4].....

如何循环代码?提前谢谢你。

您使用 lapply 的方式不正确。查看 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.

你在使用 lapply 和你在 lapply.

中声明的函数中存在一些混淆

但我认为 tidyverse 包中的函数非常适合这种任务(以不同的格式重新排列数据集)。

所以我认为向您展示如何使用 tidyverse 更有用。看看他们的教程。这将非常有用!

https://www.tidyverse.org/packages/

使用他们的功能,你可以用几行代码完成你想要的:

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}')

我在这里使用的最重要的函数是tidyr::pivot_longer。此外, %>% 运算符是一个“管道运算符”。它获取左侧的内容并在右侧的函数中用作参数。所以,x %>% f(y) 变成了 f(x, y) 所以你可以用它来重写多个操作。