R语言:移动平均计算及绘图

news2024/12/23 7:34:56

问题描述

现在有一个分日期记录DAU的数据,现在需要绘制其360,180,90,30,7日移动平均值,来观测消除了波动干扰的DAU趋势

(实际移动在股价趋势图上非常常见)

原始数据格式如下:

day

(character)

dau

(int)

2017-01-01

3098566

2017-01-02

2986435

......

......

filter函数报错_{Error in UseMethod("filter") :   "filter"没有适用于"c('integer', 'numeric')"目标对象的方法}解决方案

filter在文档中的写法会出现报错,说是不支持目标对象

报错:Error in UseMethod("filter") :   "filter"没有适用于"c('integer', 'numeric')"目标对象的方法

#原写法
library(dplyr)
x <- 1:100
filter(x, rep(1, 3))
filter(x, rep(1, 3), sides = 1)
filter(x, rep(1, 3), sides = 1, circular = TRUE)
filter(presidents, rep(1, 3))

基于上述问题,我们调用tidyverse包,对原函数进行修正

> library(tidyverse)
── Attaching packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.2 ──
✔ ggplot2 3.3.6     ✔ purrr   0.3.4
✔ tibble  3.1.6     ✔ stringr 1.4.0
✔ tidyr   1.2.0     ✔ forcats 0.5.2
✔ readr   2.1.3     
── Conflicts ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ plyr::arrange()          masks dplyr::arrange()
✖ lubridate::as.difftime() masks base::as.difftime()
✖ purrr::compact()         masks plyr::compact()
✖ plyr::count()            masks dplyr::count()
✖ lubridate::date()        masks base::date()
✖ tidyr::expand()          masks reshape::expand()
✖ plyr::failwith()         masks dplyr::failwith()
✖ dplyr::filter()          masks stats::filter()
✖ plyr::id()               masks dplyr::id()
✖ lubridate::intersect()   masks base::intersect()
✖ dplyr::lag()             masks stats::lag()
✖ plyr::mutate()           masks dplyr::mutate()
✖ reshape::rename()        masks plyr::rename(), dplyr::rename()
✖ lubridate::setdiff()     masks base::setdiff()
✖ reshape::stamp()         masks lubridate::stamp()
✖ plyr::summarise()        masks dplyr::summarise()
✖ plyr::summarize()        masks dplyr::summarize()
✖ lubridate::union()       masks base::union()

修正后的函数可以正常运行了

x <- 1:100
x1_3 <- filter(x,rep(1,3))##默认sides=2
stats::filter(x,rep(1,3),sides = 2)##加前一个后一个和当前数

filter函数详解

解决了filter函数报错的问题,我们来看一下filter是怎么实现移动平均的

首先还是1-100的自然数序列x,

filter(目标对象,系数,移动方式)

看下示例

x <- 1:100
x
stats::filter(x,rep(1,3),sides = 2)##加前一个后一个和当前数
stats::filter(x,rep(1,3),sides = 1)##加前两个数和当前数

 rep(1,3):是指将1重复3次,得到一个向量> rep(1,3) [1] 1 1 1,也就是说计算移动平均时,每一步的系数都是1

sides表示移动的方式:

        sides=1表示只参考当前值之前的数值计算,如图(黄框):第1位和第2位因为前面的数值不足,所以从第3位开始,第3位数值=第1位数值+第2位数值+第三位数值=1+2+3=6

        sides=2表示参考当前值前后的数值计算,如图(蓝框):第1位因为前面的数值不足,所以从第2位开始,第2位数值=第1位数值+第2位数值+第三位数值=1+2+3=6

同样,如果不想让前后的顺序都具有相同的权重系数,也可以自行设置,如:

x <- 1:100
x
stats::filter(x,c(0.5,1,1.5),sides = 1)##加前两个数和当前数

sides=1表示只参考当前值及其之前的数值,所以第3位开始计算

5=1*0.5+2*1+3*1.5

当然移动的位数也可以不是3位,例如是偶数位数的时候(如移动系数有4个),sides=1或sides=2时的情况如下:

sides=1时,计算1、2、3、4个数的移动平均,赋值给第4个数

sides=2时,计算1、2、3、4个数的移动平均,赋值给第2个数

x <- 1:100
x
stats::filter(x,rep(1,4),sides = 1)
stats::filter(x,rep(1,4),sides = 2)

实操:计算DAU移动平均值 

计数

##案例:计算DAU的7、30、180、360移动平均值
#导入数据
setwd('文件路径')
dau_data <- readxl::read_xlsx("dau数据.xlsx")
head(dau_data)
#调整日期排序
dau_data <- dau_data[order(dau_data$day,decreasing = FALSE),]##时间升序

#导入原始数据的时间变量是字符格式的,需要转换成日期格式
dau_data$day <- as.Date(dau_data$day,"%Y-%m-%d")

#计算移动平均
dau_data$dau_360 <- filter(dau_data$dau/360,rep(1,360),sides = 1)
dau_data$dau_7<- filter(dau_data$dau/7,rep(1,7),sides = 1)
            

这样写就可以得到N日DAU的移动平均,包含前面N-1日的数据和N日当天的数据 

如果不想包含第N日当天的数据,想用第N日之前的数据来计算如何处理呢?

我们可以在常规移动平均的结果之前加上一行NA值,实现整体数据向下平移的效果,但是因为多了一行,所以就算出来的结果无法与原数据框合并,所以需要再将最后一行数据删除即可,操作如下

dau_7 <- c(NA,filter(dau_data$dau/7,rep(1,7),sides=1))
dau_data$dau_7 <- dau_7[-length(dau_7)]##删除最后一行的数据,length(dau_7)得到的是向量的个数

dau_30 <- c(NA,filter(dau_data$dau/30,rep(1,30),sides=1))
dau_data$dau_30 <- dau_30[-length(dau_30)]

dau_90 <- c(NA,filter(dau_data$dau/90,rep(1,90),sides=1))
dau_data$dau_90 <- dau_90[-length(dau_90)]

dau_180 <- c(NA,filter(dau_data$dau/180,rep(1,180),sides=1))
dau_data$dau_180 <- dau_180[-length(dau_180)]

dau_360 <- c(NA,filter(dau_data$dau/360,rep(1,360),sides=1))
dau_data$dau_360 <- dau_360[-length(dau_360)]

dau_data

 数据结果如下:


绘图

ggplot()的参数

基础图表:ggplot(数据框,aes(X轴字段,Y轴字段))+geom_line()

叠加折线图:+geom_line(aes(x=day,y=dau_7),colour="#336699")

以此类推,叠加dau_30,dau_90等趋势线

##绘制图形
library(ggplot2)
picture <- ggplot(dau_data,aes(x=day,y=dau))+geom_line()+geom_line(aes(x=day,y=dau_7),colour="#336699")+geom_line(aes(x=day,y=dau_30),colour="#FF9900")+geom_line(aes(x=day,y=dau_90),colour="#7ab8cc")+geom_line(aes(x=day,y=dau_180),colour="#996600")+geom_line(aes(x=day,y=dau_360),colour="#006633")
##添加趋势线
picture+scale_x_date(labels = date_format("%Y-%m-%d"),breaks = date_breaks("1 months"),limits =as.Date(c("2020-01-01","2021-01-01"

结果如下:

 

但是这样做出来的图是没有图例的,而且坐标轴和标题都是默认生成,可以稍微调整一下

调整X轴坐标:scale_x_date(),参数如下:

X轴标签:labels = date_format("%Y-%m-%d")

X轴标签间隔:breaks

X轴数据范围:limits

设置一个颜色字典:scale_colour_manual(),参数如下:

values=c("颜色名称"="实际颜色16进制数字")

##绘制基础图形
picture <- ggplot(dau_data,aes(x=day,y=dau))+geom_line()
##修改横坐标格式、范围和标识粒度
picture <- picture+scale_x_date(labels = date_format("%Y-%m-%d"),
                                breaks = date_breaks("1 months"),
                                limits =as.Date(c("2020-01-01","2021-01-01")))
##修改图标标题和坐标标题
picture <- picture+theme_grey(base_family="MicrosoftYaHei")
                  +xlab("日期")
                  +ylab("DAU")
                  +ggtitle("日活跃移动平均")
                  +theme(plot.title = element_text(hjust = 0.5))
##theme(plot.title = element_text(hjust = 0.5))是为了保证标题居中

##添加移动均线和图例
picture <- picture+geom_line(aes(y=dau_7,colour="M7"))+geom_line(aes(y=dau_30,colour="M30"))+geom_line(aes(y=dau_90,colour="M90"))+geom_line(aes(y=dau_180,colour="M180"))+geom_line(aes(y=dau_360,colour="M360"))
+scale_colour_manual(values = c("M7"="#336699","M30"="#FF9900","M90"="#7ab8cc","M180"="#996600","M360"="#006633"))
picture
##修改图例的标题
picture <-  picture+theme_grey(base_family="MicrosoftYaHei")+labs(colour="移动均线")
picture

最终结果如下:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/595604.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker+Jenkins+Gitee自动化部署maven单模块项目

1.简介 各位看官老爷&#xff0c;本文为Jenkins实战&#xff0c;注重实际过程&#xff0c;阅读完会有以下收获&#xff1a; 了解如何使用Docker安装Jenkins了解如何使用Jenkins部署maven项目了解如何使用JenkinsGitee实现自动化部署 2.Jenkins介绍 相信&#xff0c;正在读这…

2023年上半年软件设计师上午真题及答案解析

1.计算机中&#xff0c;系统总线用于( )连接 A.接口和外设 B.运算器&#xff0c;控制器和寄存器 C.主存、外设部件 D.DMA控制器和中断控制器 2.在由高速缓存、主存和硬盘构成的三级存储体系中&#xff0c;CPU执行指令时需要读取数据&#xff0c;那么DMA控制…

深入理解Linux虚拟内存管理(一)

系列文章目录 Linux 内核设计与实现 深入理解 Linux 内核&#xff08;一&#xff09; 深入理解 Linux 内核&#xff08;二&#xff09; Linux 设备驱动程序&#xff08;一&#xff09; Linux 设备驱动程序&#xff08;二&#xff09; Linux 设备驱动程序&#xff08;三&#xf…

ubantu换配置源

文章目录 1.配置镜像源位置2.进入终端&#xff0c;切换到/home/user/etc/apt/3.默认这个文件是只读的&#xff0c;我们修改一下权限4.修改之前&#xff0c;我们先备份一下系统原来配置的源5.开始修改&#xff0c;打开/etc/apt/sources.list文件&#xff0c;将原来的内容删除&am…

chatgpt赋能python:Python代码怎么打包-全面介绍

Python 代码怎么打包 - 全面介绍 Python 是一种高效、易学易用、灵活多变的编程语言。对于 Python 开发者来说&#xff0c;如何将其编写的程序打包是一个必须掌握的技能。本文将着重介绍 Python 代码打包的方法及其优势&#xff0c;并提供一些实用的工具和技巧。 什么是打包?…

六级备考17天|2017年12月三套真题|翻译与写作|20:45~21:00

目录 第一套 翻译&#xff1a;太湖 中文 英文 词汇 作文 谚语题&#xff1a;respect others, and you will be respected 第二套 翻译&#xff1a;青海湖 中文 英文 词汇 第一套 翻译&#xff1a;太湖 中文 英文 词汇 太湖 Lake Tai 淡水湖 fre…

python+vue学生选课学习成绩分析及可视化分析系统

但目前国内的学习成绩分析及可视化分析信息仍然都使用人工管理&#xff0c;随着学校规模越来越大&#xff0c;同时课程信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化&#xff0c;而学习成绩分析及可视化分析能很好地解决这一问题&#xff0c;轻松应对学习成…

2020第十一届蓝桥杯Python组国赛【真题+解析+代码】

&#x1f381;2020第十一届蓝桥杯python组国赛真题 &#x1f680; 真题练习&#xff0c;冲刺国赛 &#x1f680; 2020年第十一届蓝桥python组国赛真题解析代码 博观而约取&#xff0c;厚积而薄发 &#x1f3c6;国赛真题目录 文章目录 &#x1f381;2020第十一届蓝桥杯python组国…

本地部署Jellyfin影音服务器【公网远程影音库】

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 转载自cpolar极点云的文章&#xff1a;零基础搭建私人影音媒体平台【远程访问Jelly…

华为OD机试真题 Java 实现【数组的中心位置】【2023Q1 100分】

一、题目描述 给你一个整数数组nums,请计算数组的中心位置,数组的中心位置是数组的一个下标,其左侧所有元素相乘的积等于右侧所有元素相乘的积。数组第一个元素的左侧积为1,最后一个元素的右侧积为1。如果数组有多个中心位置,应该返回最靠近左边的那一个,如果数组不存在…

chatgpt赋能python:Python代码转为C语言——提高效率的必经之路

Python代码转为C语言——提高效率的必经之路 Python是一种高级编程语言&#xff0c;具有易学易用的优点&#xff0c;因此越来越多的程序员选择使用Python来开发应用程序和脚本。但是&#xff0c;在开发高性能应用程序时&#xff0c;Python的效率问题会成为拦路虎。因此&#x…

每日一题——逆波兰表达式求值(前缀、中缀、后缀表达式的说明,库函数atoi()的解析)

文章目录 每日一题逆波兰表达式求值中缀&#xff0c;前缀&#xff08;波兰&#xff09;&#xff0c;后缀&#xff08;逆波兰&#xff09;表达式的基本概念逆波兰表达式的优点和计算方法优点计算方法 思路函数原型如何将数字入栈库函数atoi() 实现代码 每日一题 逆波兰表达式求…

chatgpt赋能python:Python代码转换:如何将代码从Python2转换为Python3

Python 代码转换&#xff1a;如何将代码从 Python 2 转换为 Python 3 作为一位有10年 Python 编程经验的工程师&#xff0c;我们都知道 Python 的两个主要版本&#xff1a;Python 2 和 Python 3。不过&#xff0c;Python 2 已于2020年正式停止支持&#xff0c;因此&#xff0c…

MySQL-7-权限与密码

一、用户授权与权限撤销 1.1、用户授权: 赋予权限:grant all on *.* to root192.168.4.% identified by "123456";从网络访问本地数据库时:只有 增删改查权限,本地登录则有所有权限。 新建用户,并赋予权限:格式&#xff1a;grant 权限列表 on 库名.表名 to 用户…

图数据库的一些概览

图数据库 图数据库是一种根据节点和边存储数据的数据库。数据以非常灵活的方式存储&#xff0c;无需遵循预定义的模型。该图形成了两个节点之间的关系&#xff0c;这种关系可以是有向的也可以是无向的。这些数据库旨在处理数据/节点之间的复杂关系。 节点用于存储数据。每个节…

chatgpt赋能python:Python-高效的SEO工具

Python - 高效的SEO工具 Python作为一种高效且易于学习的编程语言&#xff0c;广泛应用于各种领域&#xff0c;包括机器学习、数据分析、网站开发等。Python的灵活性和可扩展性也使它成为一种优秀的SEO工具。 Python在SEO中的应用 Python可用于SEO行业中的多个方面。例如&am…

IDEA内操作框文件地址生成+IDEA数组传参处理+springboot缺少依赖问题

1&#xff0c;IDEA内查询文件本地所属位置 首先在输入框内我们输入以下指令即可查询该目录下文件&#xff1a; lscd即是可进入指定目录 这样我们即可进行文件浏览与进入文件等操作 pwd即可生成该文件目录下的文件地址 2&#xff0c;IDEA数组传参处理 当结果是以数组形式被输…

chatgpt赋能python:Python信息查询的完全指南

Python信息查询的完全指南 Python是一种开源、解释性高级编程语言&#xff0c;广泛应用于数据科学、机器学习、人工智能、Web开发和自动化任务等领域。Python的简洁易读、高效快速的特点&#xff0c;使其成为程序员和企业的首选语言。然而&#xff0c;学习Python并不容易&…

Docker v24.0.0 发布

导读Docker 24.0.0 现已发布&#xff0c;具体更新内容如下&#xff1a; New 引入对 containerd 作为内容存储的实验性支持&#xff08;替换现有的存储驱动程序&#xff09;。moby/moby#43735, other moby/moby pull requests--hostCLI flag 现在支持 ssh:// 主机地址中的路径组…

Java基础(8)——java的异常机制初步

引出 java异常机制初步 异常是什么 程序运行时&#xff0c;产生非正常的结果。 java异常体系 异常的体系&#xff1a; 异常是可抛出的 不同的异常处理&#xff1a; 如果一个异常类继承Exception,可检测异常&#xff1a;必须处理继承RuntimeException,运行时异常&#xff0c…