基础语法: 输入输出"

chooseCRANmirror(graphics = FALSE, ind = 1)
knitr::opts_chunk$set(echo = TRUE,
                      message = FALSE,
                      warning = FALSE,
                      out.width="100%")

if (!require(pacman)) install.packages("pacman")

p_load(
  lubridate,
  here,
  rio,
  tidyverse,
  drhur
)

知识点

基础概念

面对对象的编程语言

summary(wvs7)
summary(wvs7$age)

现学现练

R的Polymorphism让我们能够用通用方法或函数来处理那些尚未定义的对象类型,除summary()外,plot()是另外一个Polymorphism的例子。请使用plot()对两种不同的对象进行处理,看看结果如何。

plot(wvs7$age)
plot(wvs7$age, wvs7$incomeLevel)

命令

OOP之信仰:不触碰数据,让命令去做。
语法:<命令名>(<目标数据>, <条件1>, <条件2>, ...)

{height=500}

light <- function(finger){
  {{shadow <- finger + 5}}
}
handShadow <- light(finger = 3)
handShadow

数据包

{height=300}

<-

赋值符,assign()命令默认行为的简写

语法:<名称> <- <对象>

aValidObject <- 1:5
aValidObject

->, =, <<-

R中赋值的四种符号:

  1. assign()
  2. <-
  3. <<-
  4. =

Why <-

a <- 12
25 -> b

何时用

median(y <- 1:10); y
median(x = 1:10); x
new_counter <- function() {
  i <- 0
  function() {
    # do something useful, then ...
    i <<- i + 1
    i
  }
}

命名规则

  1. 不以数字开头 (错误: 1stday)
  2. 除了 ._以外没有其他特殊符号(错误: M&M)
  3. 区分大小写 (X != x), !表示“非”/“否”,!=表示“不等于”
  4. 如需必要请勿重写内置命令 (避免: list <- c(1:5))
  5. 表意命名

请创建一个合规和不合规的对象:

# 创建一个不合规的对象

# 5var_name <- data_frame($education)


# 一个合规对象

var_name5 <- data_frame(wvs7$education)

现学现练

question("请选择所有合规的变量名?",
  answer("my_data_frame <- data_frame(wvs7$education)", correct = TRUE),
  answer("mydata&frame <- data_frame(wvs7$education)"),
  answer("MyDataFrame <- data_frame(wvs7$education)", correct = TRUE),
  answer("1data_frame <- data_frame(wvs7$education)"),
  incorrect = "Incorrect")

数据输入

内置数据

data()

现学现练

data里选择一个数据打开并通过summary检查其中的变量:


# 举例

data(uspop)
summary(uspop)

可直读数据

语法: <名称><- <读取命令>(<数据路径>)

df_rds <- readRDS("aDataset.rds")
df_txt <- read.table("D:/aDataset.txt")
df_csv <- read.csv("./aDataset.csv")

调用包读取数据

通过library或者require调用数据包,然后使用其中的命令。

# SPSS, Stata, SAS
library(haven)
df_spss <- read_spss("<FileName>.sav")
df_stata <- read_dta("<FileName>.dta")
df_sas <- read_sas("<FileName>.sas7bdat")  

# 表格的快速导入
library(reader)
df_csv <- read.csv("<FileName>.csv")
df_table <- read.table("<FileName>.csv/txt")

# Excel表格
library(readxl)
df_excel <- read_excel("<FileName>.xls")
df_excel2 <- read_excel("<FileName>.xlsx")

# JSON (JavaScript Object Notation)
library(rjson)
df_json <- fromJSON(file = "<FileName>.json" )

# XML/Html
library(xml)
df_xml <- xmlTreeParse("<url>")
df_html <- readHTMLTable(url, which=3)

数据读取界的瑞士军刀:rio

library(rio)
df_anything <- import(<AnyTypeOfData>)

数据种类

  1. 向量 (vector) ⍻
  2. 矩阵 (matrix) ✓
  3. 数据框 (data frame)
  4. 列 (list)
  5. 阵列 (array)

向量

执行组合功能的命令c()可用来创建向量

vec_integer <- c(1, -2, NA)
vec_double <- c(1.5, -2.34, 1/3)

注意: 1. NA表示的是: not available
2. 单个向量中的数据必须拥有相同的类型(数值型、字符型或逻辑型)

现学现练

生成一个包含1-100中全部偶数的向量:

# hint: help(seq)
x <- seq(2,100,by=2)

vec_chr <- c("牛", "^_^", "R is hard,but I can nail it.")

现学现练

生成一个a-z的字母序列:

vec_letters <- c("a", "b", "c", "d", "e")
letters[1:26]

vec_tf <- c(TRUE, TRUE, FALSE)
vec_tf
# c(TRUE, TRUE, FALSE) == c(1, 1, 0)

现学现练

假设x为包含(1,1,0)的向量,将它转化为逻辑向量:


x <- c(1, 1, 0)
x <- as.logical(x)

vec_fac <- factor(c(1, 2, 2, 3))
vec_ord <- ordered(c(1, 2, 2, 3))
vec_fac2 <- factor(c(1, 2, 2, 3), 
                   levels = c(3, 2, 1), 
                   labels = c("Apple", "Pear", "Orange"))

现学现练

在拿到一个数据集后,先要对数据有个大致的了解。

先查看wvs7数据里的变量分别是什么类型:


str(wvs7)

查看数据集里incomeLevel这个变量的性质:


class(wvs7$incomeLevel)

查看incomeLevel的取值和每个取值的频次情况:


table(wvs7$incomeLevel)

#`as.POSIXct`与`as.POSIXlt`的区别
ct <- as.POSIXct("2023-03-20 10:11:12")
lt <- as.POSIXlt("2023-03-20 10:11:12")
unlist(ct)
unlist(lt)
Sys.time() # 获取当前时间
today()   # 获取当日的 年月日
now()  # 获取当日的 年月日 时分秒  时区
# CST为操作时电脑ip所在的时区

# The full pack
time1 <- Sys.time()
time2 <- as.POSIXlt(Sys.time())
time2$wday # week of the day

## 如果我只在乎日期呢?
Sys.Date()
date1 <- as.Date("2019-01-02")
class(date1)  # 查看数据类型

时间数据的瑞士军刀:lubridate

library(lubridate)

ymd("20221016")
mdy("10-16-2022")
dmy("16/10/2022")
ymd_hms("2022-10-16 09:00:00", tz = "Etc/GMT+8")
OlsonNames()

现学现练

当面对顺序不一样的向量时,如:

x=c("20190101",'01012019','021901')

应该怎么识别时间呢?

#help(parse_date_time)
parse_date_time(x,orders = c("ymd","dmy","dym"))

矩阵

矩阵(matrix)见drhur("algebra")

阵列

阵列(array): 顾名思义就是列的“阵”,可用于记录二维以上的数据,可通过array命令创建。

# 创建两个长度不同的向量。
vector1 <- c(5, 9, 3)
vector2 <- c(10, 11, 12, 13, 14, 15)

# 把这些向量输入到数组中。
result <- array(c(vector1, vector2), dim = c(3, 3, 2))
result

列(list): 可包含多种不同类型对象的“串”。

ls_monks <- list(name = c("Wukong Sun", "Sanzang Tang", "Wuneng Zhu", "Wujing Sha"),
                 power = c(100, 20, 90, 40),
                 buddha = c(TRUE, TRUE, FALSE, FALSE))

ls_monks

数据框

数据框(Data Frame):一种特殊的列/矩阵

在Excel中:

在R中:

df_toy <- data.frame(female = c(0,1,1,0),
           age = c(29, 39, 38, 12),
           name = c("Iron Man", "Black Widow", "Captain Marvel", "Captain America"))

df_toy

在Rstudio中:

数据属性

  1. class, typeof:查询变量属性
  2. nchars:获取字符串的长度
  3. levels:获取或设置因子的级别
  4. nrow:返回指定矩阵的行数
  5. ncol:用于返回指定矩阵的列数
  6. dim:列向量张成的子空间,即维度
vec_integer <- c(1, -2, NA)

vec_double <- c(1.5, -2.34, 1/3)

vec_chr <- c("牛", "^_^", "R is hard,but I can nail it.")

vec_fac <- factor(c(1, 2, 2, 3))

ls_monks <- list(name = c("Wukong Sun", "Sanzang Tang", "Wuneng Zhu", "Wujing Sha"),
                 power = c(100, 20, 90, 40),
                 buddha = c(TRUE, TRUE, FALSE, FALSE))

df_toy <- data.frame(female = c(0,1,1,0),
           age = c(29, 39, 38, 12),
           name = c("Iron Man", "Black Widow", "Captain Marvel", "Captain America"))

class(vec_double)
typeof(vec_integer)

nchar(vec_chr)
levels(vec_fac)

length(vec_double)
length(ls_monks)
length(df_toy)

nrow(df_toy)
ncol(df_toy)
dim(df_toy)

现学现练

将下面的向量转化为numeric类型:

c(FALSE, TRUE)
# help(as.numeric)
as.numeric(c(FALSE, TRUE))

wvs7里的性别变量“female"的数值是“TRUE”、“FALSE”

在具体分析的时候,字符型变量不便操作,可以把它转换为数值型的0 1变量。


as.numeric(wvs7$female) - 1

数据输出

语法:<命令>(<待存数据>,file = <存储路径>)

储存为R数据

saveRDS(df_toy, file = "df_toy.rds")
save(df_toy, ls_monks, file = "test.rdata")

储存为csv文件

write.csv(df_toy, file = "toy.csv")

提示: 如果你的数据是中文的,可能会出现存储csv乱码现象。

当然了,你可以通过专门软件包或“瑞士军刀”(rio::export)把数据以STATA, SPSS, SAS Excel, JSON, Matlab, HTML等格式存储下来, 不过你真的想这样吗?

STATA (.dta, \<14): 3.16 G = R (.rds): 0.05 G

| Method | Average Time | Minimum | Maximum | |:-----------------|:----------------:|:-----------:|:-----------:| | base::readRDS | 19.65 | 18.64 | 21.01 | | fst::read_fst | 1.39 | 0.56 | 3.41 | | haven::read_sav | 104.78 | 101.00 | 111.85 | | qs::qread | 3.33 | 3.00 | 4.24 |

: 四种在R中读取GSS数据的方式所用的平均时间(以秒计)

| Method | Average Time | Minimum | Maximum | File Size | |:----------------|:----------------:|:-----------:|:-----------:|:-------------:| | base::saveRDS | 98.36 | 93.09 | 103.24 | 30.9 MB | | fst::write_fst | 2.70 | 1.86 | 4.05 | 122.1 MB | | qs::qsave | 5.03 | 4.35 | 6.62 | 44.6 MB |

: 在R中写入GSS数据(及文件大小)所用的平均时间

总结



Try the drhur package in your browser

Any scripts or data that you put into this service are public.

drhur documentation built on May 31, 2023, 6:03 p.m.