可视化:RStudio 入门知识 其三

243 阅读2分钟

本文已参加「新人创作礼」活动,一起开启掘金创作之路。

这次带来的是 RStudio 的入门知识。

各个知识点后面都有对应的小练习哦,大家可以利用刚刚学到的知识来试着写写看!

Data Frame 数据框

我们将要用到的数据集大都保存在data frame (数据框)中, 在本节中我们会学习如何创建一个数据框, 如何选择其中一部分数据, 如何修改它, 如何对它排序等.

  • 什么是数据框?
  • 一个例子
  • 查看data.frame的结构
  • 注意观察!
  • 创建一个data.frame
  • 创建一个data.frame(2)
  • 选择数据框的一个子集
  • 选择数据框的一个子集(2)
  • 修改数据框中的元素
  • 增加行和列
  • 合并两个数据框
  • 排序
  • data.frame的排序
# 什么是数据框?
# 数据框类似矩阵, 有两个维度: 行, 列
# 区别是, 矩阵里面的元素必须是同一种类型的, 
# 而数据框只要求每一列中的元素是同一种类型的
# 这一特性使得数据框也类似于列表
# 但数据框的每一组列(列是数据框的组成单元)只能是向量, 这一点跟列表不一样
# 因此, 数据框可以认为是一种介于 矩阵和列表 之间的结构
# 这带来了灵活度,同时也有规范度
# 这使得数据框非常适合存储真实世界的很多数据(结构化的数据)
# 结构化数据的通用存储原则: 
#     每一列代表一个特征/变量, 
#     每一行代表一个样本/观测

# 一个例子 head, tail
cars # R自带的一个数据集
iris # R自带的一个数据集

head(cars)
tail(cars)
head(cars, n=3)
tail(cars, n=4)

head(iris)

# 查看data.frame的结构 dim, str
dim(cars)
dim(iris)

str(cars)
str(iris)

class(iris[[5]])

# 注意观察!
# data.frame与list的关系

# 创建一个data.frame

fruit = c("apple", "banana", "cherry")
price = c(10, 5, 20)
data.frame(fruit, price)
df1 = data.frame(fruit, price)
df1
str(df1)

# 创建一个data.frame(2)
df2 = data.frame(fruit, price, stringsAsFactors=FALSE)
df2
str(df2)

# names
names(df2)
colnames(df2)
rownames(df2)
dimnames(df2)

# 选择数据框的一个子集
# data.frame 同时具有matrix和list的一些特性
df2[1,1]
df2[1,]
df2[-1,]
df2[,2]
df2[,-2]
class(df2[,2])
class(df2[1,])
df2[,2]
df2[,2,drop=FALSE]
class(df2[,2,drop=FALSE])

df2[1]
str(df2[1])
class(df2[1])

df2[[1]]
str(df2[[1]])
class(df2[[1]])

df2$fruit
str(df2$fruit)
class(df2$fruit)

df2['fruit']
df2[['fruit']]

# 选择数据框的一个子集(2)
# 同样支持逻辑值作为index
df2[c(T,F,T),]
df2[, c(T,F)]
df2[df2$price < 10,]

# 修改数据框中的元素
df2[1,2] = 9
df2
df2[df2$price < 10,]

# 增加列和行
amount = c(3,3,1)
df2[3] = amount
df2
df2[[3]] = amount
df2

df2[3] = NULL
df2
df2$amount = amount
df2

df2[4,]
df2[4,] = c("damson", 8, 1)
df2
str(df2)

# 增加一行的正确方法? 见下面

# 合并两个数据框
# 按照行合并
df2 = data.frame(fruit, price, amount, stringsAsFactors=FALSE)
df2
str(df2)

df3 = data.frame(fruit='damson', price=8, amount=2, stringsAsFactors=FALSE)
rbind(df2, df3)
df4 = rbind(df2, df3)
str(df4)

# 按照列合并
df5 = data.frame(fresh=c(T, T, F, T), discount=seq(0.1, 0.4, 0.1))
df5
df6 = cbind(df4, df5)
df6

# 按照key合并
df7 = data.frame(fruit=c("apple", "banana", "cherry", "elderberry"), soldout=c(F,F,F,F))
df8 = merge(df6, df7)
df8

# Q: 通过计算, 为df6 增加一列: cost, 记录了购买每种水果的实际花费
df6$cost = df6$price * (1 - df6$discount) * df6$amount
df6

# Q: 突然接到电话, 说折扣小于15%的不要买, 重新计算新的cost


# 排序
sort(c(4,3,5,2,1))
sort(c(4,3,5,2,1), decreasing=T)

sort(c(4,3,5,NA,2,1))
sort(c(4,3,5,NA,2,1), na.last=T)

order(c(4,3,5,2,1))
c(4,3,5,2,1)[order(c(4,3,5,2,1))]

order(c(4,3,5,2,1), decreasing=T)

# data.frame的排序
df2[order(df2$price),]

df6[order(df6$cost),]

习题

# Q1: 创建一个数据框(名为shopping),三列, 包含六种蔬菜的name,price,amount信息, 
#     其中蔬菜的name要以char而非factor形式保存
# Q2: 增加一列, 名为 discount
# Q3: 根据以上信息, 再在数据框中增加一列 cost, 为每种蔬菜的花费
# Q4: 计算花费的均值
# Q5: 选出三种花费最少的蔬菜, 将这三行保存为 cheap3
# Q6: 用另一种方式重做Q5

# Q7: mtcars是R中自带的数据集, 通过帮助文档了解它
# Q8: 从mtcars中选出一个子集, 需要满足下列全部条件:
#     自动挡的四缸车或六缸车
#     每加仑汽油可以行驶超过19英里
#     车重小于3000磅

# Q9: R中自带了不少数据集(根据本机已安装的package不同而不同), 
#     可以通过函数: data() 查看
#     你知道第57个数据集是什么吗?
#     hint: x = data()

Reading & Writing data files 读写文件

数据文件是用来记录和存储数据的文件. 对于数据分析,机器学习等领域,最常用的数据文件采用如下的组织方式:

  • 每行代表一个样本
  • 每列代表一个Variable(变量)/Feature(特征)

文件的常用格式:

  • CSV ( Comma Separated Values ) file 及其变种
  • Excel

其它格式:

  • JSON
  • DataBase 数据库
  • Matlab,SAS,SPSS等

读取文件:

  • read.table
  • read.csv, read.csv2
  • read.delim
  • readxl::read_excel

写入文件:

  • write.table
  • write.csv
  • save, load

关于文件路径和工作目录:

  • 相对路径和绝对路径
  • 工作目录

文件的编码:

  • 各种编码介绍
  • utils::read.csv, readr::read_csv 中的编码选项
# 读取 CSV ( Comma Separated Values ) file 及其变种
read.csv("./data/R0_09_student01.csv")
stu1 = read.csv("./data/R0_09_student01.csv")
str(stu1)

read.csv("./data/R0_09_student01noheader.csv")
read.csv("./data/R0_09_student01noheader.csv", header=F)
stu1nh = read.csv("./data/R0_09_student01noheader.csv", header=F)
str(stu1nh)

colnames(stu1nh) = c("id","math","eng")

# CSV 的变种
read.csv("./data/R0_09_student01space.txt")
read.table("./data/R0_09_student01space.txt")
read.table("./data/R0_09_student01space.txt",header=T)

?read.table # 观察各个变种的区别

# Excel
# R默认不支持读取Excel文件, 需要安装第三方包, 比如 readxl, openxlsx 等
# 关于包的安装和使用, 参见下一节
library(readxl)
read_excel("./data/R0_09_student01.xlsx")


# JSON
# JSON 也是一种通用的,纯文本的文件格式, 它包含了描述自己的信息, 容易被理解
stu1j = rjson::fromJSON(file="./data/R0_09_student01.json")
as.data.frame(stu1j)

# DataBase 连接数据库
# 需要安装 MySQL Server
# 安装packages: DBI,  RMySQL
library(DBI)
con = dbConnect(RMySQL::MySQL(),
         user="user1", password="pwd1",
         dbname="liuxiao", host="192.168.56.101")
rs = dbSendQuery(con, "select * from test;")
fetch(rs)
on.exit(dbDisconnect(con))

# Matlab, SAS, SPSS
# packages: R.matlab, foreign

# 写入CSV文件
data.frame()
write.csv(df1, file="./data/df1.csv")
write.csv(df1, file="./data/df1.csv", row.names=F)

# 写入Rdata
save(df1, file="./data/df1.Rdata")
load(file="./data/df1.Rdata")

# 关于文件路径和工作目录
# 相对路径和绝对路径
# 工作目录 getwd, setwd, RStudio

# 各种编码介绍
# utils::read.csv, readr::read_csv 中的编码选项
read.csv("./data/R0_09_cars_GB18030.csv", fileEncoding = "UTF-8")
read.csv("./data/R0_09_cars_GB18030.csv", fileEncoding = "GB18030")

read_csv("./data/R0_09_cars_GB18030.csv", locale = locale(encoding = "GB18030"))

习题

# Q1: 从网络上采集新型冠状病毒肺炎COVID-19的实时数据, 
# 数据来源可以使用: http://m.medsci.cn/wh.do
# 将国内的数据保存在名为 china_covid_19_yyyymmdd 的数据框中
# yyyymmdd代表采集时的年月日
# 需采集5个不同日期的数据, 保存在5个数据框中
# 并将这5个数据框保存在硬盘上(同时使用Rdata和CSV格式保存)

# Q2: 同上, 采集世界各个国家(除了中国)的数据
# 国外的数据保存在名为 world_covid_19_yyyymmdd 的数据框中
# 需采集5个不同日期的数据, 保存在5个数据框中
# 并将这5个数据框保存在硬盘上(同时使用Rdata和CSV格式保存)

# 注意数据框中各个变量/列中元素的数据类型(字符?数值?)

# hint: 你可能会需要用到这个函数 "sub"

read.csv("./data/china_covid_19_20200315.txt", sep="\t")

About R Packages 关于R包

  • 如何安装包
  • 在安装时指定mirror
  • 使用源码编译安装
  • 载入已安装的包
  • 查看全部已安装的包
  • 如何卸载包
  • 查看某个包的帮助文档
# 安装一个包 knitr, 指定安装源
install.packages("knitr",
                 repos = "https://mirrors.tuna.tsinghua.edu.cn/CRAN/")

# 使用源码编译安装
# 有时候会出现这个情况: 
# 在一个安装源上, 某个包的二进制版本和源代码版本都存在,
# 且源代码版本更加新,
# 这时候, R会提示: 是否要安装更加新的源代码版本(需要编译)

# 载入已经安装的包(其实是告诉R将这个包列入搜索空间)
library("readxl")
library(readxl)

# 载入包之后, R会将这个包列入搜索空间, 这样就可以调用这个包中的函数,
# 但也有其它方法直接调用
readxl::read_excel("./data/R0_09_student01.xlsx")

# 将某个包从搜索空间移除
detach("package:readxl")
read_excel("./data/R0_09_student01.xlsx")
readxl::read_excel("./data/R0_09_student01.xlsx")

# 查看全部已安装的包
installed.packages()

# 如何卸载包
remove.packages("readxl")

# 查看某个包的帮助文档
help(package="readxl")
help(package="base")

国内的mirror

如何查看全球mirror

  • cran.r-project.org/mirrors.htm…
  • 其实还有很多没有收录在这个官方列表中的mirror, 比如国内很多云服务提供商(阿里云,腾讯云等)都有自己的mirror.

修改RStudio的默认安装mirror

Tools -> Global Options -> Packages -> Package Management

使用RStudio安装package出错的时候可以尝试使用R安装