写在前面
本笔记的目的是使得使用人员快速掌握和复习R语言的语法
Question & Answer
R中的数是否和python一样是自动类型?
R中的数与Python中的数在类型处理上有所不同.虽然R和Python都具有自动类型系统,但在细节和实现上有一些差异.
R中的数值类型
数值类型:
- ==默认数值类型:在R中,所有的数字(例如
1
,2.5
)默认都是double
类型,即双精度浮点数.R没有专门的整数类型,除非显式地指定.==- ==整数类型:可以使用
L
后缀来定义整数.例如,x <- 5L
表示x
是整数类型,而不是默认的双精度浮点数.==类型转换:
- 自动转换:R会自动进行类型转换.例如,如果你将一个整数和一个浮点数相加,结果将是浮点数(双精度浮点数).
- 强制转换:可以使用
as.integer()
,as.numeric()
,as.double()
等函数来显式地转换数据类型.例如,as.integer(3.14)
会将3.14
转换为整数3
.数值表示:
- 浮点数精度:R使用IEEE 754标准表示双精度浮点数,这与Python中的浮点数表示方式类似.浮点数在计算中可能会出现精度问题.
Python中的数值类型
数值类型:
- 整数类型:Python中的整数是
int
类型,表示为任意精度的整数.例如,x = 5
表示x
是整数.- 浮点数类型:Python中的浮点数是
float
类型,表示为双精度浮点数.例如,y = 3.14
表示y
是浮点数.类型转换:
- 自动转换:Python也会自动进行类型转换.例如,如果你将一个整数和一个浮点数相加,结果将是浮点数.
- 强制转换:可以使用
int()
,float()
,complex()
等函数来显式地转换数据类型.例如,int(3.14)
会将3.14
转换为整数3
.数值表示:
- 浮点数精度:Python使用IEEE 754标准表示双精度浮点数,这与R中的表示方式一致.浮点数在计算中也可能会出现精度问题.
总结
- 自动类型:R和Python都具有自动类型系统,数字类型的转换和运算都是自动进行的.
- 默认类型:R默认将所有数字视为双精度浮点数,除非明确指定为整数.Python区分整数和浮点数,并且整数是任意精度的.
- 强制转换:两者都提供了显式转换函数来改变数据的类型.
因此,虽然R和Python在类型处理上有相似之处,但它们在默认数值类型和类型转换方面存在一些差异.
在R中字符串的单双引号有区别吗?
在R语言中,字符串的单双引号没有实际区别.你可以使用单引号(
'
)或双引号("
)来定义字符串,它们的功能完全相同.选择哪一种主要是个人或项目的风格偏好.示例
使用双引号:
rstr1 <- "Hello, World!"
使用单引号:
rstr2 <- 'Hello, World!'
注意事项
引号的嵌套:
- 如果你的字符串中包含了双引号,使用单引号可以避免转义.例如:
rstr3 <- 'He said, "Hello, World!"'
- 同样,若字符串中含有单引号,则可以使用双引号:
rstr4 <- "It's a nice day."
转义字符:
- 当使用相同类型的引号时,需要使用转义字符来包括引号.例如:
rstr5 <- "He said, \"Hello, World!\""
一致性:
- 在代码中使用一致的引号风格可以提高可读性.例如,如果在一个字符串中使用双引号定义字符串,应该保持一致使用双引号或单引号.
总的来说,R语言对单双引号没有强制要求,选择哪一种可以根据个人喜好和代码风格指南来决定.
R中变量和python一样都是智能变量吗?
在R和Python中,变量的行为类似,但也有一些关键的不同点.两者都采用了动态类型系统,变量的类型在运行时决定,但具体实现有所不同.
R中的变量
- 动态类型:R中的变量是动态类型的,变量的类型在运行时决定.例如,
x <- 5
将x
赋值为整数,x <- "Hello"
再将x
赋值为字符串,R会自动处理这些类型的变化.- 对象系统:R中的所有数据都是对象.变量只是指向这些对象的名称.例如,
x <- 5
使x
成为指向整数对象5
的引用.- 内存管理:R使用垃圾回收机制来管理内存,自动处理不再使用的对象.
Python中的变量
- 动态类型:Python中的变量也是动态类型的,变量的类型在运行时决定.例如,
x = 5
将x
赋值为整数,x = "Hello"
再将x
赋值为字符串,Python会自动处理这些类型的变化.- 对象系统:Python中的所有数据也是对象.变量是对象的引用.例如,
x = 5
使x
成为指向整数对象5
的引用.- 内存管理:Python同样使用垃圾回收机制来管理内存.
主要差异
赋值操作:
- R:变量赋值使用
<-
或=
.例如,x <- 5
或x = 5
.- Python:变量赋值使用
=
.例如,x = 5
.对象类型:
- R:所有数据都是对象,包括函数和环境.R有更强的数据处理和统计分析功能.
- Python:所有数据也是对象,Python的对象系统更为通用,适用于更广泛的编程任务.
函数和数据类型:
- R:函数本身也是对象,可以作为数据传递和操作.
- Python:函数也是对象,支持更复杂的面向对象编程特性.
总结
R和Python的变量都是动态类型的,可以自动处理类型的变化.两者的变量本质上都是指向对象的引用,并且都使用垃圾回收机制来管理内存.主要区别在于语法和特定的语言特性.
R的切片和python的切片有什么区别?
在R语言中,切片(slicing)是一个常用的操作,用于从向量,矩阵,列表和数据框中提取子集.切片操作通常涉及到按范围选择数据或按条件过滤数据.以下是R语言中切片的详细使用方法:
向量(Vector)
基本切片
按位置切片:选择连续的元素.
rvec <- c(10, 20, 30, 40, 50) slice <- vec[2:4] # 结果是 c(20, 30, 40)
按逻辑条件切片:选择符合条件的元素.
rslice <- vec[vec > 25] # 结果是 c(30, 40, 50)
矩阵(Matrix)
行和列切片
按行切片:选择特定行或行范围.
rmat <- matrix(1:9, nrow=3, ncol=3) row_slice <- mat[1:2, ] # 选择第1和第2行,结果是一个2x3矩阵
按列切片:选择特定列或列范围.
rcol_slice <- mat[, 2:3] # 选择第2和第3列,结果是一个3x2矩阵
按行列切片:选择特定行和列.
rslice <- mat[1:2, 2:3] # 选择第1到第2行和第2到第3列,结果是一个2x2矩阵
列表(List)
元素切片
按位置切片:选择特定位置的元素.
rlst <- list(a=1, b=2, c=3, d=4) slice <- lst[2:3] # 返回一个包含第2和第3个元素的子列表
按名称切片:选择特定名称的元素.
rlst <- list(name="John", age=25, scores=c(90, 80, 85)) slice <- lst[c("name", "scores")] # 返回一个包含"name"和"scores"的子列表
数据框(Data Frame)
行和列切片
按行切片:选择特定行或行范围.
rdf <- data.frame(name=c("John", "Jane"), age=c(28, 30), score=c(85, 90)) row_slice <- df[1:2, ] # 选择第1和第2行,结果是一个数据框
按列切片:选择特定列或列范围.
rcol_slice <- df[, 1:2] # 选择第1和第2列,结果是一个数据框
按条件切片:根据条件选择行.
rage_slice <- df[df$age > 28, ] # 选择age大于28的所有行
使用示例
向量切片:
rvec <- c(1, 2, 3, 4, 5) print(vec[2:4]) # 输出 2, 3, 4
矩阵切片:
rmat <- matrix(1:9, nrow=3, ncol=3) print(mat[1:2, ]) # 输出前两行的所有列 print(mat[, 2:3]) # 输出所有行的第2和第3列
列表切片:
rlst <- list(a=1, b=2, c=3, d=4) print(lst[2:3]) # 输出包含第2和第3个元素的子列表
数据框切片:
rdf <- data.frame(name=c("John", "Jane"), age=c(28, 30), score=c(85, 90)) print(df[1:1, ]) # 输出第一行 print(df[, 2:3]) # 输出第2和第3列 print(df[df$age > 28, ]) # 输出age大于28的所有行
总结
在R中,切片操作使得从各种数据结构中提取子集变得灵活和高效.根据需要,可以按位置,范围或条件选择数据.对于不同的数据结构(向量,矩阵,列表,数据框),切片的具体操作有所不同,但整体思路是一致的,即通过中括号操作选择所需的数据部分.
R语言是否支持指定步长切片?
==在R语言中,步长切片(即每隔一定步长选择元素)并不像Python那样直接支持.==然而,你可以通过其他方法实现类似的功能.以下是一些实现步长切片的常见方法:
1. 使用
seq
函数 你可以使用
seq
函数生成具有步长的索引向量,然后使用这些索引进行切片.示例
rvec <- c(10, 20, 30, 40, 50, 60, 70) indices <- seq(1, length(vec), by=2) # 生成步长为2的索引 slice <- vec[indices] # 结果是 c(10, 30, 50, 70)
2. 使用逻辑索引
另一种方法是创建一个逻辑向量,用于选择步长切片的元素.
示例
rvec <- c(10, 20, 30, 40, 50, 60, 70) logical_indices <- rep(c(TRUE, FALSE), length.out=length(vec)) # 每隔一个元素为TRUE slice <- vec[logical_indices] # 结果是 c(10, 30, 50, 70)
3. 使用
subset
和seq
函数结合 对于数据框,可以结合
subset
和seq
函数来实现步长切片.示例
rdf <- data.frame(name=c("John", "Jane", "Alice", "Bob", "Eve"), age=c(28, 30, 25, 35, 40)) indices <- seq(1, nrow(df), by=2) # 生成步长为2的索引 slice_df <- df[indices, ] # 结果是包含第1, 3, 5行的数据框
总结
虽然R语言中没有内置的步长切片操作,但你可以使用
seq
函数,逻辑索引或其他方法来实现类似的功能.这些方法提供了灵活的方式来处理数据并获得步长切片的效果.
&和&&有什么区别?
==||
和|
类似==
在R语言中,
&&
和&
都是用来进行逻辑与(AND)操作的,但它们之间存在一些关键的区别:
短路行为:
&&
具有短路行为.如果第一个操作数是FALSE
(或者NA
或NULL
),则整个表达式的结果将立即确定为FALSE
,而不会计算第二个操作数.&
不具有短路行为.无论第一个操作数的值是什么,&
都会计算两个操作数.向量化:
&
可以用于向量化操作.这意味着它可以应用于两个相同长度的向量,并返回一个新的向量,其中每个元素都是对应位置元素的逻辑与结果.&&
不能用于向量化操作.它只能用于标量或单个元素的逻辑比较.使用场景:
- 当你需要在第一个条件不满足时避免执行第二个条件的计算时,使用
&&
.- 当你需要对两个向量进行逐元素的逻辑与操作时,使用
&
.下面给出一些示例来说明这些区别:
R# 使用 &&,如果第一个条件为 FALSE,则不计算第二个条件 a <- FALSE b <- 1/0 # 这将产生一个错误,因为除以零 result_and = a && b # 结果是 FALSE,且 b 不会被计算 # 使用 &,即使第一个条件为 FALSE,也会计算第二个条件 a <- FALSE b <- 2 result_and_vec = a & b # 结果是 FALSE,但 b 会被计算
在实际编程中,选择使用
&&
还是&
取决于你的具体需求,特别是是否需要避免在某些条件下执行不必要的计算.关于向量化操作的例子
r# 创建两个向量 vector1 <- c(TRUE, FALSE, TRUE, NA, FALSE) vector2 <- c(TRUE, TRUE, FALSE, TRUE, NA) # 使用 & 进行向量化的逻辑与操作 result_vector <- vector1 & vector2 # 输出结果 print(result_vector)
关于复数
在R语言中,复数的处理非常简单和直观.R支持复数的基本运算,函数计算以及复数序列的创建.下面是一些关于复数的操作和使用方法:
1. 复数的表示
在R中,复数由实部和虚部组成,虚部用
i
或1i
表示.例如:Rz <- 3 + 4i # 复数 z = 3 + 4i
这里,
3
是实部,4i
是虚部.2. 复数的基本运算
R支持对复数的基本算术运算,例如加法,减法,乘法和除法:
Rz1 <- 3 + 4i z2 <- 1 + 2i # 加法 z1 + z2 # 结果为 4 + 6i # 减法 z1 - z2 # 结果为 2 + 2i # 乘法 z1 * z2 # 结果为 -5 + 10i # 除法 z1 / z2 # 结果为 2.2 - 0.4i
3. 获取复数的实部和虚部
使用
Re()
和Im()
函数可以分别获取复数的实部和虚部:RRe(z1) # 返回3,实部 Im(z1) # 返回4,虚部
4. 复数的共轭
复数的共轭(即实部不变,虚部取相反数)可以使用
Conj()
函数计算:RConj(z1) # 返回 3 - 4i
5. 复数的模与辐角
- 模(即复数的绝对值)可以使用
Mod()
函数计算:RMod(z1) # 返回5,即 sqrt(3^2 + 4^2)
- 辐角(即复数的相位角)可以使用
Arg()
函数计算:RArg(z1) # 返回辐角,以弧度表示
6. 复数的极坐标表示
R中可以将复数转换为极坐标表示,其中模为半径,辐角为角度:
R# 使用模和辐角来构造复数 r <- Mod(z1) # 模 theta <- Arg(z1) # 辐角 z_polar <- r * exp(1i * theta) # 极坐标形式
7. 复数序列
可以通过复数生成序列,例如使用
seq()
函数:Rseq(1 + 1i, 10 + 10i, by = 1 + 1i)
这将生成从
1 + 1i
到10 + 10i
的复数序列,每一步递增1 + 1i
.8. 复数函数
R中的一些常用数学函数也可以处理复数,例如:
- 平方根:
sqrt(z1)
- 指数函数:
exp(z1)
- 对数函数:
log(z1)
- 三角函数:
sin(z1)
,cos(z1)
示例:计算复数的平方根
Rsqrt(z1) # 返回复数的平方根
通过这些功能,R可以轻松处理复数运算,并支持复数的各种数学操作.在数据分析和科学计算中,这些功能非常实用.
复数的创建方法
在R语言中,可以通过直接赋值或者使用函数来创建复数:
直接赋值创建复数: 使用虚部标识
i
或1i
直接创建复数.Rz1 <- 3 + 4i # 创建复数 z1 = 3 + 4i z2 <- 5i # 创建纯虚数 z2 = 0 + 5i
使用
complex()
函数创建复数:complex()
函数允许通过指定实部和虚部来创建复数.Rz3 <- complex(real = 2, imaginary = 3) # 创建复数 z3 = 2 + 3i z4 <- complex(modulus = 5, argument = pi/4) # 使用模和辐角创建复数
在第二种方式中,
modulus
参数表示复数的模,argument
参数表示复数的辐角(以弧度为单位).复数作为条件判断时的转换结果
在R语言中,当复数用于条件判断时,系统会检查复数的实部.如果实部为非零,则条件判断为 TRUE
;如果实部为零,则检查虚部.如果虚部再为0,则为FALSE
.
例如:
Rz <- 3 + 4i if (z) { print("条件为TRUE") } else { print("条件为FALSE") }
在这个例子中,实部为3,所以条件为
TRUE
,输出结果为"条件为TRUE"
.
在R中,什么数据会在条件判断中作为False和True?
在R语言中,不同类型的数据在条件判断中的表现各不相同.通常情况下,
if
和while
等条件判断语句会依据逻辑值TRUE
和FALSE
进行判断.以下是一些常见数据类型在条件判断中的转换规则:1. 逻辑值(
logical
类型)
TRUE
: 直接作为条件判断时为真.FALSE
: 直接作为条件判断时为假.Rif (TRUE) { print("条件为TRUE") # 将被执行 } if (FALSE) { print("条件为FALSE") # 不会被执行 }
2. 数值(
numeric
类型)
- 0: 在条件判断中为
FALSE
.- 非零值: 在条件判断中为
TRUE
.Rif (0) { print("条件为TRUE") # 不会被执行 } if (1) { print("条件为TRUE") # 将被执行 }
3. 字符串(
character
类型)
- 空字符串 (
""
): 在条件判断中为FALSE
.- 非空字符串: 在条件判断中为
TRUE
.Rif ("") { print("条件为TRUE") # 不会被执行 } if ("Hello") { print("条件为TRUE") # 将被执行 }
4. 空对象(
NULL
)
NULL
: 在条件判断中为FALSE
.Rif (NULL) { print("条件为TRUE") # 不会被执行 }
5. 空向量(
logical(0)
,numeric(0)
,character(0)
等)
- 长度为0的向量: 在条件判断中为
FALSE
.空向量的判断通常不会触发任何输出或执行条件语句.Rif (logical(0)) { print("条件为TRUE") # 不会被执行 }
6. NA值(
NA
)
NA
: 在条件判断中会被视为未定义,R会发出警告并返回NA
结果,通常需要通过函数is.na()
进行显式检查.Rif (NA) { print("条件为TRUE") # 不会被执行,且R会发出警告 }
7. 数据框或列表
- 非空数据框或列表: 在条件判断中为
TRUE
.- 空数据框或列表: 在条件判断中为
FALSE
.Rdf <- data.frame(x = 1:3) if (df) { print("条件为TRUE") # 将被执行 } df <- data.frame() if (df) { print("条件为TRUE") # 不会被执行 }
总结
R语言中的条件判断基于逻辑值转换,但需要注意不同数据类型的行为.通过这些规则,你可以更好地控制条件语句的执行,避免意外结果.
参数stringsAsFactors的介绍
在R语言中,
stringsAsFactors
参数用于控制是否将读取的数据中的字符串(character
类型)自动转换为因子(factor
类型).这是一个与R的历史默认行为相关的参数.因子(Factor)简介
因子是一种用于表示分类数据的特殊数据类型.在统计建模和数据分析中,因子非常有用,因为它们可以有效地编码分类变量,并在建模时自动处理.
例如,性别,地区等分类数据通常会被表示为因子类型.
stringsAsFactors
参数的作用 在使用
read.csv()
或data.frame()
等函数时,R默认会将字符串自动转换为因子.这种行为在R的早期版本(R 4.0.0 之前)非常普遍,但在现代数据处理中,不总是需要将字符串转换为因子类型,因此这个参数变得重要.
stringsAsFactors = TRUE
(默认行为):
- 字符串列会自动转换为因子.
- 这种转换对于需要分类数据的场景很有用,比如数据建模或处理有限类别的变量.
Rdata <- read.csv("data.csv", stringsAsFactors = TRUE) str(data) # 检查数据结构,字符串列会被转换为因子
stringsAsFactors = FALSE
:
- 字符串列保持为
character
类型.- 这是现代数据处理的推荐做法,因为在需要时可以手动将特定列转换为因子,而不需要自动处理.
Rdata <- read.csv("data.csv", stringsAsFactors = FALSE) str(data) # 字符串列保持为字符类型
为什么需要关注
stringsAsFactors
参数?
数据类型控制:在处理数据时,因子类型不适合所有情况.对于大部分数据操作(如字符串匹配,文本分析等),直接使用
character
类型更加方便.如果数据被不小心转换为因子类型,可能会带来额外的复杂性.避免错误:在不需要因子的情况下,如果字符串被自动转换为因子类型,可能导致不可预见的错误.例如,尝试对因子列进行字符串操作时,结果可能与预期不符.
R版本差异:在R 4.0.0之后,
stringsAsFactors
的默认值已经从TRUE
改为FALSE
,以符合现代数据处理的习惯.因此,如果使用旧版本R,或在不同环境中分享代码,明确设置stringsAsFactors
是一种更安全的做法.总结
stringsAsFactors = TRUE
:字符串将自动转换为因子类型.这在需要分类变量时非常有用.stringsAsFactors = FALSE
:字符串将保留为character
类型.这是处理文本数据和大部分现代数据操作时的推荐设置.通过明确设置
stringsAsFactors
参数,你可以更好地控制数据的类型,避免不必要的因子转换带来的复杂性.我可以理解为这个参数相当于把数据转换为独热码类似的数据类型吗?
你可以部分这样理解,但
stringsAsFactors
和独热码(One-Hot Encoding)之间有一些重要区别.让我们先理解这两者的本质,然后比较它们的关系.因子(Factor)与独热码的区别
因子(Factor):
- 因子在R中是一种特殊的数据类型,用于表示分类数据.它包含一个取值集合,称为"水平"(levels).
- 因子是一个整数向量,每个整数值对应于特定的分类标签(水平).虽然看起来像字符串,但因子实际上是用==整数==存储的.
- 在数据分析和统计建模中,因子可以用于处理分类变量.例如,
lm()
函数会自动识别因子,并将其视为分类变量来进行回归分析.示例:
Rgender <- factor(c("Male", "Female", "Female", "Male")) print(gender)
输出:
[1] Male Female Female Male Levels: Female Male
独热码(One-Hot Encoding):
- 独热码是一种用于表示分类数据的编码方式,每个分类标签都会转换为一个二进制向量,其中仅一个位置为1,其他位置为0.
- 独热码在机器学习中特别常用,尤其是在需要将分类变量作为输入特征时.每个分类标签会被展开成一个多列的向量,每列代表一个分类的可能值.
示例: 如果性别有两个类别 "Male" 和 "Female",那么独热编码可能如下:
Male: [1, 0] Female: [0, 1]
stringsAsFactors
与 独热码的比较
因子(
stringsAsFactors = TRUE
):
- 将字符串转换为因子后,每个类别被映射为一个整数,而不是一个二进制向量.因子并不会像独热码那样展开为多列,而是以整数形式存在.
- 在统计建模中,因子可以自动处理分类变量并生成虚拟变量(dummy variables),这些变量在建模时类似于独热编码的效果.
独热码:
- 独热编码会将每个分类标签直接转换为多列的二进制向量.这种编码方式对于机器学习模型(如神经网络)非常有用,但它会增加数据的维度.
结论
stringsAsFactors
参数的作用类似于将字符串转换为一种方便进行统计分析的分类变量表示形式(即因子),但它并不会自动生成独热码式的多列表示.如果你需要将分类变量转换为独热码,可以使用R中的model.matrix()
或其他包(如caret
,dummies
)来实现.因此,因子与独热码 的关系可以这样理解:
- 因子是对分类变量的一种紧凑表示,它内部使用整数编码,而独热码则是将分类变量展开为多个二进制列.
- 虽然两者都用于处理分类数据,但使用场景和实现方式不同.
什么是R语言的工作空间,如何理解?
R语言的工作空间(Workspace)是一个保存当前R会话中所有对象(如变量,数据框,函数等)的环境.理解工作空间的几个关键点包括:
对象的存储:当你在R中创建变量,数据框或其他对象时,这些对象会被存储在工作空间中.你可以随时访问,修改和使用这些对象.
保存和加载:你可以将工作空间保存到一个文件中,以便以后恢复.保存的文件通常以
.RData
或.rda
为后缀.你可以使用save.image()
函数保存整个工作空间,使用load()
函数加载保存的工作空间.管理工作空间:你可以使用
ls()
函数查看当前工作空间中的所有对象,用rm()
函数删除不需要的对象,用rm(list=ls())
删除所有对象.工作目录:工作空间的文件通常存储在当前工作目录中.可以使用
getwd()
查看当前工作目录,使用setwd()
更改工作目录.会话管理:R语言的工作空间与当前会话相关联.当你关闭R会话时,可以选择是否保存工作空间的状态.如果保存了,下次启动R时可以恢复到之前的状态.
通过有效地管理工作空间,你可以更好地组织和处理数据,提高工作效率.
abline(h = 0)
可以用来添加平行于x轴的参考线,那么平行于y轴的呢?
在R语言中,
abline()
函数用于添加平行于x轴的参考线,但要添加平行于y轴的参考线,你可以使用abline(h=值)
来添加平行于x轴的线,而使用abline(v=值)
来添加平行于y轴的线.具体来说:
abline(h=值)
:添加平行于x轴的水平线.abline(v=值)
:添加平行于y轴的垂直线.例如,如果要在x轴的值为5的位置添加一条水平线,可以使用:
rabline(h=5)
如果要在y轴的值为10的位置添加一条垂直线,可以使用:
rabline(v=10)
x[]
和 x
在赋值操作中有不同的含义?
x[] 表示取 x 的全部元素作为子集.这与 x 本身不同,比如
rx <- c(1,4,6.25) x[] <- 999 x ## [1] 999 999 999 x <- c(1,4,6.25) x <- 999 x ## [1] 999
在R语言中,
x[]
和x
在赋值操作中有不同的含义.
x[] <- 999
:这行代码使用方括号表示对向量x
的所有元素进行赋值.在这里,x[]
指的是x
向量中的所有元素,而999
是新赋给这些元素的值.因此,向量x
中的每个元素都被设置为999
.
x <- 999
:这行代码则是直接将整个向量x
替换为单一的数值999
.在这个操作中,x
不再是一个向量,而是一个单一的数值.因此,当你打印x
时,你会得到[1] 999
,表示x
现在只包含一个元素,其值为999
.简单来说,使用方括号
[]
进行赋值时,你正在改变向量中元素的值;而不使用方括号直接赋值时,你正在将整个向量替换为一个新的值.
如何理解"下标可以是与向量等长的逻辑表达式,一般是关于本向量或者与本向量等长的其它向量的比较结果"
在R语言中,使用逻辑表达式作为下标来索引向量是一种非常强大的方法,可以让你根据条件选择向量中的元素.这里的关键点是"下标"可以是一个逻辑向量,其长度与被索引的向量
x
相同.每个逻辑值(TRUE
或FALSE
)对应于x
中的相应元素.让我们分解一下你给出的例子:
rx <- c(1, 4, 6.25) x[x > 3] ## [1] 4.00 6.25
在这个例子中:
x
是一个包含三个元素的向量:1
,4
,和6.25
.x > 3
是一个逻辑表达式,它将x
中的每个元素与数值3
进行比较,生成一个逻辑向量:FALSE
,TRUE
,TRUE
.这里的FALSE
对应于1
(因为1
不大于3
),而两个TRUE
分别对应于4
和6.25
(因为它们都大于3
).- 当我们使用这个逻辑向量作为下标(
x[x > 3]
),R语言会从x
中选择那些对应于TRUE
值的元素.在这个例子中,就是选择4
和6.25
.所以,当你看到"下标可以是与向量等长的逻辑表达式",它意味着你可以创建一个逻辑向量,其长度与你要索引的向量相同,然后使用这个逻辑向量来选择满足特定条件的元素.这是一种条件索引,允许你基于元素的值或其他条件来选择它们.
R语言中的seq函数是如何使用的?
在R语言中,
seq()
函数用于生成一个序列.这个函数非常灵活,可以用来创建等差数列,等比数列,或者根据更复杂的规则生成序列.下面是一些基本的使用示例:
生成等差数列: 使用
from
,to
, 和by
参数.from
是序列的起始值,to
是序列的结束值,by
是步长(每次增加的量).rseq(from = 1, to = 10, by = 1) # 生成从1到10的等差数列 # [1] 1 2 3 4 5 6 7 8 9 10
生成等比数列: 使用
from
,to
, 和by
参数,其中by
是每次乘以的因子.rseq(from = 1, to = 100, by = 2) # 生成从1到100的等比数列,每次乘以2 # [1] 1 2 4 8 16 32 64
指定序列的长度: 使用
length.out
参数来指定序列的长度.如果同时指定from
,to
, 和length.out
,by
将自动计算.rseq(from = 1, to = 10, length.out = 5) # 从1到10生成5个数的序列 # [1] 1.000000 3.333333 5.666667 8.000000 10.000000
使用
along.with
参数:along.with
参数允许你根据另一个对象的长度来生成序列.rx <- 1:5 seq(along.with = x) # [1] 1 2 3 4 5
生成不规律的序列: 使用
from
和length.out
,不使用by
,可以生成一个起始值和长度确定,但步长不固定的序列.rseq(from = 0, length.out = 10) # 从0开始,生成长度为10的序列 # [1] 0.0000000 0.3333333 0.6666667 1.0000000 1.3333333 1.6666667 2.0000000 2.3333333 2.6666667 3.0000000
使用
...
来传递其他参数:seq()
函数还可以接受其他参数,如by
,这些参数可以通过...
传递给内部的seq_len()
函数.rseq(from = 0, by = 0.5, length.out = 10) # [1] 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5
seq()
函数是R语言中非常基础且强大的工具,可以用来生成各种类型的序列,以满足不同的数据分析和编程需求.
NA
的类型
在R语言中,
NA
表示缺失值,它可以出现在不同类型的数据中.R提供了多种类型的NA
,以适应不同的数据类型.以下是一些常见的NA
类型:
NA
或NA_real_
:
- 这是最常见的缺失值类型,用于数值向量(
numeric
).
NA_integer_
:
- 用于整数向量(
integer
).虽然R中通常使用NA
表示所有缺失值,但NA_integer_
明确表示整数类型的缺失值.
NA_complex_
:
- 用于复数向量(
complex
),包含实部和虚部都是缺失值的复数.
NA_character_
:
- 用于字符向量(
character
),表示文本数据中的缺失值.
NA_bool_
或NAlogical_
:
- 用于逻辑向量(
logical
),表示布尔值(TRUE
或FALSE
)中的缺失值.
NA_omit
:
- 通常用于模型拟合中,表示在模型中应该被省略的值.
NA因子类型_
:
- 在因子(
factor
)向量中,NA
可以表示缺失值,因子类型的缺失值在内部也是以NA_integer_
存储.每种类型的
NA
都可以使用is.na()
函数来检测:ris.na(NA) # TRUE is.na(NA_integer_) # TRUE is.na(NA_real_) # TRUE is.na(NA_complex_) # TRUE is.na(NA_character_) # TRUE is.na(NA_bool_) # TRUE
在R中处理数据时,理解不同类型的
NA
是非常重要的,因为它们在数据清洗,分析和建模中的行为可能不同.例如,某些函数可能需要显式地处理NA
,而其他函数可能默认忽略它们.此外,不同类型的NA
在数学运算和统计函数中的表现也可能不同.
在R语言中向量和列表有什么区别?
在R语言中,向量(vector)和列表(list)是两种基本的数据结构,它们之间有几个关键的区别:
元素类型:
- **向量:是一个一维数组,其中的元素必须是同一类型.**例如,一个向量可以包含整数,字符或逻辑值,但不能同时包含这些类型.
- 列表:可以包含不同类型的元素,每个元素可以是向量,矩阵,列表或其他R对象.
结构:
- 向量:是线性的,元素按顺序排列.
- 列表:是嵌套的,每个元素可以是一个单独的列表,形成更复杂的结构.
创建方式:
- 向量:使用
c()
函数创建,例如c(1, 2, 3)
.- 列表:使用
list()
函数创建,例如list(a = 1, b = "text", c = list(1, 2))
.访问方式:
- 向量:使用下标访问单个元素,例如
vector[1]
.- 列表:可以使用
$
访问列表中的元素,例如list$a
,或者使用下标访问,例如list[[1]]
.长度:
- 向量:使用
length()
函数来获取元素的数量.- 列表:使用
length()
函数来获取列表中元素的数量,但列表的每个元素本身可能包含多个元素.命名:
- 向量:可以是命名的,但通常不命名.
- 列表:可以为每个元素命名,这使得列表在存储具有不同属性的数据时更加灵活.
用途:
- 向量:通常用于存储数值数据,进行数学运算.
- 列表:用于存储复杂的数据结构,例如函数的参数列表,或者在函数返回多个不同类型的结果时使用.
这些区别使得向量和列表在R语言中有不同的应用场景,根据需要选择合适的数据结构是非常重要的.
在例子
rx <- c(1,"A",3) typeof(x) ## [1] "character" print(x) ## [1] "1" "A" "3"
在R语言中,尝试创建一个包含不同类型元素的向量,比如
c(1, "A", 3)
,将会导致一个警告,并自动将整个向量转换为字符向量.这是因为R语言中的向量要求所有元素必须是同一类型.在这个例子中,数字1
和3
会被转换为字符,整个向量会变成字符向量,包含元素"1"
,"A"
和"3"
.这里是R语言如何处理上述代码的示例:
R# 尝试创建一个包含数字和字符的向量 mixed_vector <- c(1, "A", 3) # 查看结果 print(mixed_vector)
执行这段代码后,输出将是:
[1] "1" "A" "3"
并且可能会有一个警告信息,指出向量中的元素被转换为字符类型.这是因为R语言在处理混合类型的向量时,会将所有元素转换为最能够容纳所有元素的数据类型,在这个例子中就是字符类型.
以c(1, c(2,3, c(4,5)))
为例,如何理解"原子类型的各个元素除了基本类型相同,还不包含任何嵌套结构"?
在R语言中,"原子类型的各个元素除了基本类型相同,还不包含任何嵌套结构"这句话的意思是指一个原子向量的元素都是同一种基本数据类型(如整数,字符,逻辑值等),并且这些元素没有进一步的嵌套.
以
c(1, c(2, 3, c(4, 5)))
为例,来解释这一点:
基本类型:在R中,
c(1, c(2, 3, c(4, 5)))
的元素类型是整型(integer
).所有元素都是整数,这满足了基本类型相同的条件.嵌套结构:原子向量的定义中,元素不能包含其他结构.如果你用
c()
函数创建一个向量,它的元素都是基础数据类型的值,而不是向量,列表或其他复杂结构.虽然在你给出的例子中使用了嵌套的c()
,实际上R会将这些嵌套的c()
自动"拉平"成一个单一的原子向量.具体来说,当你使用
c(1, c(2, 3, c(4, 5)))
时,R会将所有的嵌套结构自动展开成一个平坦的向量.因此,最终结果是一个原子向量:1, 2, 3, 4, 5
.这个结果中的元素都是整数,没有其他嵌套的向量或列表.总结来说,原子向量的定义确保了其中的元素都是同一种基本类型,并且没有更深层次的嵌套结构.即使你在创建向量时使用了嵌套的
c()
,R会将其展平成一个单一的原子向量.关于原子向量
原子向量是R语言中的一种基本数据结构,用于存储同一类型的元素.它有以下几个特点:
单一数据类型:原子向量的所有元素必须是同一种基本数据类型,例如整数,字符,逻辑值或双精度数(数值型).例如,
c(1, 2, 3)
是一个整型原子向量,c("a", "b", "c")
是一个字符型原子向量.不含嵌套结构:原子向量的元素不能是其他向量,列表或复杂结构.所有元素都必须是基本数据类型的值,而不是其他容器结构.例如,
c(1, 2, 3)
是有效的,但c(1, c(2, 3))
在构造时会被展平成c(1, 2, 3)
.长度固定:原子向量的长度是固定的,即它包含的元素数量在创建后不会改变.你可以通过
length()
函数查看原子向量的长度.总之,原子向量是R中最基础的数据存储形式,确保所有元素都是简单的一维数据,没有复杂的嵌套结构.
如何理解R语言中的NULL,并与NA做对比?
在R语言中,
NULL
和NA
都用于表示缺失或无效的值,但它们的含义和用途不同:
NULL
:
- 定义:
NULL
表示对象不存在或为空.它用于表示没有值或无效的对象.- 用法:
NULL
可以用于指示某个对象未被定义,或作为函数返回值时表示没有数据.例如,函数可能返回NULL
以表明没有结果.- 特点:
NULL
是一种特殊的对象,不属于任何数据类型.它的长度是0.rx <- NULL length(x) # 返回 0
NA
:
- 定义:
NA
表示数据中的缺失值或未知值.它是数据分析中处理缺失数据的常用标记.- 用法:
NA
用于表示在数据集中缺少的信息.例如,在数据框中某个变量的值缺失时,通常使用NA
表示.- 特点:
NA
是一个特殊的标记,属于不同的数据类型(如NA_integer_
,NA_real_
,NA_character_
等),用来指示缺失值.它的长度和类型与原数据相同.ry <- c(1, NA, 3) length(y) # 返回 3 is.na(y) # 返回 FALSE TRUE FALSE
总结:
NULL
表示对象不存在或为空,长度为0.NA
表示缺失值或未知值,是数据中的一个有效元素,具有特定的长度和数据类型.
关于attributes(x)的辨析
在R中,
attributes(x) <- NULL
这一操作会将对象x
的所有属性(如名称,维度等)移除.让我们逐步解析你给出的代码和其变化:在R语言中,
table()
函数用于创建一个频次表,显示数据中每个值的出现次数.它非常适用于分类数据的汇总和分析.以下是table()
函数的基本用法和特点:基本用法
rtable(x)
x
:要创建频次表的向量或因子变量.示例
rdata <- c(1, 2, 1, 3, 2, 1) freq_table <- table(data) print(freq_table)
输出:
1 2 3 3 2 1
这表示值
1
出现了 3 次,值2
出现了 2 次,值3
出现了 1 次.多维表格
table()
函数也可以处理多个变量,创建多维频次表.==这里要求多个变量的长度相同==
例如:
rdata1 <- c("A", "B", "A", "B", "A") data2 <- c("X", "X", "Y", "Y", "Y") multi_table <- table(data1, data2) print(multi_table)
输出:
data2 data1 X Y A 3 1 B 1 2
这表示变量
data1
和data2
组合的频次表.==这里得到的是组合观察类型==
你提供的多维频次表数据如下:
data2 data1 X Y A 3 1 B 1 2
这个数据可以通过以下几个方面来解读:
1. 表格结构
- 行(行名称):
data1
的取值A
和B
.- 列(列名称):
data2
的取值X
和Y
.2. 频次解释
每个单元格中的数值表示
data1
和data2
组合的频次.例如:
A
和X
的组合频次为3
:即在数据中data1
为A
且data2
为X
的观察数是 3.A
和Y
的组合频次为1
:即在数据中data1
为A
且data2
为Y
的观察数是 1.B
和X
的组合频次为1
:即在数据中data1
为B
且data2
为X
的观察数是 1.B
和Y
的组合频次为2
:即在数据中data1
为B
且data2
为Y
的观察数是 2.3. 分析
这个频次表允许你分析两个变量之间的关系和交互:
data1
为A
时:data2
为X
的频次较高(3次),而data2
为Y
的频次较低(1次).data1
为B
时:data2
为X
和Y
的频次比较均匀(X
1次,Y
2次).4. 可视化
你可以用图表来更直观地理解这些数据,例如使用条形图或堆叠条形图来展示每个
data1
类别下不同data2
类别的频次.特点
- 分类汇总:用于快速汇总分类数据的频次.
- 自动排序:输出表格按行和列自动排序.
- 属性:返回的表格对象具有
names
属性,指示每个类别的标签.
table()
函数是处理和汇总分类数据的强大工具,广泛用于数据探索和统计分析中.
创建表格对象:
rx <- table(c(1, 2, 1, 3, 2, 1))
x
是一个表格对象,显示了每个值出现的频次.它的输出是:1 2 3 3 2 1
查看属性:
rattributes(x)
在这里,你会看到
x
的属性信息,通常包括names
(表示表格的维度名称).移除属性:
rattributes(x) <- NULL
这行代码将
x
的所有属性设为NULL
,即移除所有属性.再次查看属性:
rattributes(x)
这时会返回
NULL
,因为属性已经被移除.检查数据类型:
rtypeof(x)
x
的数据类型仍然是table
,但移除了属性后,它只是一个基本的向量.打印
x
:rprint(x)
打印的结果会依然是原始数据,但不再有表格的维度名称.输出可能如下:
1 2 3 3 2 1
总结: 通过
attributes(x) <- NULL
,你将表格对象x
的所有额外属性(如维度名称)移除了,使其变回一个没有任何附加属性的基本向量.数据本身(频次计数)保持不变,但不再有表格的结构或标签.
关于attr 函数
attr()
函数在R语言中用于获取或设置对象的属性.它主要用于处理对象的元数据,比如名称,维度等.以下是attr()
函数的基本用法和示例:基本用法
获取属性:
rattr(x, "属性名")
x
:对象"属性名"
:你想获取的属性名称设置属性:
rattr(x, "属性名") <- value
value
:要设置的属性值示例
获取属性:
rx <- c(1, 2, 3) attr(x, "names") # 试图获取名为 "names" 的属性
在这个例子中,
x
并没有names
属性,因此结果会是NULL
.设置属性:
rx <- c(1, 2, 3) attr(x, "names") <- c("a", "b", "c") print(x)
输出:
a b c 1 2 3
这里,我们为向量
x
设置了一个names
属性,使其每个元素都有一个名称.查看现有属性:
rattributes(x) # 查看所有属性
这会显示
x
的所有属性,包括刚设置的names
.应用场景
- 数据分析:可以用来给数据框,向量等对象设置自定义的属性.
- 调试和开发:在开发自定义函数和数据结构时,可以利用
attr()
来管理和检查对象的元数据.
attr()
是一个灵活的函数,适用于管理对象的属性,以便更好地组织和分析数据.
矩阵的维数修改
rx <- matrix(1:12, nrow=3, ncol=4) attr(x, "dim") # 等同于 dim(x) ## [1] 3 4 print(x) ## [,1] [,2] [,3] [,4] ## [1,] 1 4 7 10 ## [2,] 2 5 8 11 ## [3,] 3 6 9 12 dim(x) <- c(4,3) print(x) ## [,1] [,2] [,3] ## [1,] 1 5 9 ## [2,] 2 6 10 ## [3,] 3 7 11 ## [4,] 4 8 12
修改 dim 属性就将向量转换成矩阵(数组),或修改了矩阵的性质,元素按列次序重排填入新的矩阵.==有限按照列来排列==
如何理解"R 允许 dim 仅有一个元素,这对应于一维向量,与普通的没有 dim 属性的向量有区别.另外要注意,取矩阵子集 时如果结果仅有一列或一行,除非用了 drop=FALSE 选项,结果不再有 dim 属性,退化成了普通向量."?
在R语言中,
dim
属性用于描述对象的维度.理解以下两个概念对理解该说明至关重要:1. 一维向量与普通向量的区别
一维向量(有
dim
属性):R 允许一维向量具有dim
属性,即dim
仅有一个元素,这种一维向量被称为具有维度的向量.例如,当你创建一个具有维度属性的向量时,它可以被看作是一个只有一维的矩阵:rx <- 1:5 dim(x) <- c(5) print(x)
在这里,
x
是一个一维向量,但通过dim(x) <- c(5)
,它具有了dim
属性,使其可以被视作一个具有1行5列的矩阵.普通向量(没有
dim
属性):普通的向量没有dim
属性,通常仅表示一个一维数据集合.例如:ry <- 1:5 print(y)
在这里,
y
是一个普通向量,没有dim
属性.2. 矩阵子集的取法
当你从矩阵中提取子集时,如果结果只有一行或一列,默认情况下,R 会将其简化为普通向量,而不是保留矩阵的结构.这是因为
drop = TRUE
是默认选项,意味着如果提取的结果维度低于矩阵的原始维度,则结果会被"降维".例如,考虑以下矩阵和子集提取:
rmat <- matrix(1:6, nrow = 2, ncol = 3) print(mat) # [,1] [,2] [,3] # [1,] 1 3 5 # [2,] 2 4 6 # 提取第1行 row1 <- mat[1, ] print(row1) # [1] 1 3 5 # 提取第1列 col1 <- mat[, 1] print(col1) # [1] 1 2
在这两个提取操作中:
row1
是一维向量,dim
属性不再存在,因为提取的结果只有一行.col1
也是一维向量,因为提取的结果只有一列.使用
drop = FALSE
如果希望提取的子集保持矩阵的维度(即使它只有一行或一列),可以使用
drop = FALSE
选项:r# 提取第1行,保持矩阵结构 row1_matrix <- mat[1, , drop = FALSE] print(row1_matrix) # [,1] [,2] [,3] # [1,] 1 3 5 # 提取第1列,保持矩阵结构 col1_matrix <- mat[, 1, drop = FALSE] print(col1_matrix) # [,1] # [1,] 1 # [2,] 2
在这两个操作中,
drop = FALSE
保持了矩阵的维度属性,确保结果是具有适当维度的矩阵,而不是简化为一维向量.总结
- 一维向量的
dim
属性:允许一维向量具有维度,虽然它看起来像一个向量,但实际上具有了类似矩阵的结构.- 矩阵子集的降维:默认情况下,提取矩阵的子集时,如果结果只有一行或一列,结果会简化为一维向量.使用
drop = FALSE
可以避免这种简化,保持结果的矩阵结构.
在R语言中Date()函数怎么使用?
Date()
函数在R语言中用于创建日期对象.通常,你会使用as.Date()
函数将字符型数据转换为日期格式.例如:R# 创建一个日期对象 date <- as.Date("2024-08-30") # 查看日期 print(date)
如果你的日期格式不同,可以使用
format
参数指定.例如:R# 指定日期格式 date <- as.Date("30-08-2024", format="%d-%m-%Y")
关于一个计算周岁函数的讨论
rage.int <- function(birth, now){ age <- year(now) - year(birth) sele <- (month(now) * 100 + mday(now) < month(birth) * 100 + mday(birth)) ## sele 是那些没有到生日的人 age[sele] <- age[sele] - 1 age }
看起来很奇怪,但是你要注意,这个函数是经过向量化的
第一步
age <- year(now) - year(birth)
生成一个int型的向量,计算的是未经处理的初始年龄
第二步
sele <- (month(now) * 100 + mday(now) < month(birth) * 100 + mday(birth))
生成一个对应的逻辑向量来决定之后一步的不满周岁处理是针对于哪些元素的
第三步
age[sele] <- age[sele] - 1
按照条件访问,对于TRUE的变量进行减一操作
第四步
返回age向量
如何理解"时间区间允许开始时间比结束时间晚,用 lubridate::int_standardize() 可以将时间区间标准化成开始时间 小于等于结束时间."
lubridate::int_standardize()
函数用于标准化时间区间,确保开始时间小于或等于结束时间.它会将时间区间调整为标准格式,即开始时间总是早于或等于结束时间.如果时间区间的开始时间晚于结束时间,int_standardize()
会自动交换这两个时间点.示例如下:rlibrary(lubridate) # 创建一个时间区间,开始时间晚于结束时间 interval1 <- interval(ymd_hms("2024-08-30 15:00:00"), ymd_hms("2024-08-30 12:00:00")) # 标准化时间区间 standardized_interval <- int_standardize(interval1) print(standardized_interval)
在这个示例中,
interval1
的开始时间晚于结束时间,int_standardize()
会调整为开始时间早于结束时间的标准格式.
使用library()加载多个包时如何操作?
使用
library()
加载多个包时,你需要分别调用library()
函数来加载每一个包.library()
函数一次只能加载一个包.以下是如何同时加载多个包的示例:r# 加载多个包 library(dplyr) library(ggplot2) library(lubridate)
你可以按顺序逐个加载需要的包.如果你有很多包需要加载,也可以将它们放在一个代码块中以方便管理.
更高效的方法
使用
pacman
包:pacman
包提供了一个p_load()
函数,可以一次性加载多个包,如果某个包没有安装,p_load()
会自动安装它.r# 安装 pacman 包(如果尚未安装) if (!requireNamespace("pacman", quietly = TRUE)) { install.packages("pacman") } # 使用 pacman 加载多个包 pacman::p_load(dplyr, ggplot2, lubridate)
使用
lapply()
结合library()
: 如果你有一个包名的向量,可以使用lapply()
函数来循环加载这些包.r# 包名向量 packages <- c("dplyr", "ggplot2", "lubridate") # 加载所有包 lapply(packages, library, character.only = TRUE)
这些方法可以使加载多个包的过程更加高效和简洁.
paste()函数是如何使用的?
rmy_day <- as.POSIXct(paste("01",my_str,sep=""),format='%d%b%y')
paste()
函数在 R 中用于将多个字符串连接成一个字符串.它可以通过设置sep
参数来指定连接符.在你的例子中,paste()
用于将字符串合并为一个符合特定格式的日期字符串.示例解释
rmy_str <- "Aug2024" # 例子中的字符串,表示月份和年份 my_day <- as.POSIXct(paste("01", my_str, sep=""), format='%d%b%y')
解释步骤
paste("01", my_str, sep="")
:
paste()
将"01"
(日期中的日部分)和my_str
(月份和年份)连接起来.sep=""
指定了连接符为空,即直接拼接.- 结果是
"01Aug2024"
.这表示 2024 年 8 月 1 日.
as.POSIXct()
:
- 将合成的字符串
"01Aug2024"
转换为POSIXct
日期时间对象.format='%d%b%y'
指定了输入字符串的格式,其中%d
是日期(01),%b
是月份缩写(Aug),%y
是年份(24).总结
paste()
: 用于将多个字符串拼接成一个字符串,sep
参数控制连接符.as.POSIXct()
: 将拼接后的字符串转换为日期时间对象.在你的例子中,
paste()
生成了一个符合日期格式的字符串,然后as.POSIXct()
将其转换为日期时间对象.
Note
R的简介
R语言是一种用于统计计算和数据分析的编程语言,其设计初衷是为了支持数据分析和图形显示.以下是对R语言的详细介绍,包括其运行原理的解释:
R语言概述
背景与历史
- R语言:由罗伯特.詹特尔曼(Robert Gentleman)和罗斯.伊哈卡(Ross Ihaka)于1993年在新西兰奥克兰大学开发,基于S语言的设计理念.S语言是贝尔实验室的一个统计编程语言.
- 开源特性:R语言是GNU通用公共许可证(GPL)下的开源软件,任何人都可以自由使用和修改.
核心特点
- 统计计算:内置了大量的统计和数学函数,适合复杂的统计分析.
- 数据处理与可视化:提供丰富的绘图功能和数据处理包.
- 扩展性:拥有丰富的扩展包和社区支持,几乎可以满足所有数据分析需求.
R语言的运行原理
==解释型语言==
- 解释执行:R是一种解释型语言,这意味着R代码在执行时由解释器逐行读取和执行,而不是先编译成机器码再执行.这种方式适合快速开发和实验,但可能在执行效率上逊色于编译型语言.
R语言的执行流程
- 输入阶段:用户通过R语言的交互式环境(如R控制台,RStudio)输入代码,或者通过R脚本文件(.R)提交代码.
- 解析阶段:R解释器将输入的代码解析成抽象语法树(AST).这一步骤将代码转化为一种内部表示形式,方便后续处理.
- 执行阶段:R解释器根据抽象语法树执行相应的操作.这包括计算表达式,调用函数,访问数据等.
- 结果输出:执行结果返回给用户,结果可以是计算结果,图形展示或者其他形式的输出.
数据处理机制
- ==对象模型==:R语言中的数据以对象的形式存在,例如向量(vector),矩阵(matrix),列表(list),数据框(data frame)等.每种对象都有其特定的操作方式.
- 内存管理:R使用垃圾回收机制来管理内存,自动回收不再使用的对象.这减少了内存泄漏的风险.
- 数据访问:R通过向量化操作来提高效率,避免了显式的循环操作,这类似于Python中的NumPy数组.
扩展与包管理
- 包管理:R语言的功能可以通过安装和加载不同的包(packages)来扩展.包是由函数,数据集和文档组成的集合.用户可以使用
install.packages()
安装包,并用library()
加载包.- ==CRAN==:R的官方包仓库是CRAN(Comprehensive R Archive Network),提供了大量的第三方包和资源.
==考虑更换国内镜像源==
Rprofile
文件位于R安装目录下的library/base/R/Rprofile
添加北大镜像源
请在
~/.Rprofile
后面添加一行:(需要使用管理员权限安装)Roptions("repos" = c(CRAN="https://mirrors.pku.edu.cn/CRAN/"))
图形系统
- 基础图形系统:R内置的基础图形系统允许用户绘制各种图形,并提供对图形的全面控制.使用
plot()
,hist()
等函数可以创建散点图,直方图等.- ggplot2:ggplot2是R语言中一个强大的图形绘制包,基于"语法图形"理论,允许用户以图形层的方式创建复杂的图形.通过
ggplot()
函数及其相关图形对象(如geom_point()
,geom_line()
)来创建图形.并行计算
- 并行处理:虽然R是解释型语言,但它支持并行计算.用户可以利用
parallel
包,foreach
包等实现多核处理,优化计算性能.结论
R语言因其强大的统计计算能力,灵活的数据处理功能以及丰富的可视化工具,广泛应用于数据分析,统计建模,科研和商业分析领域.其解释型语言的特性使得R语言适合快速原型开发和数据探索,但可能在大规模数据处理时需要通过并行计算或编写高效的代码来优化性能.
R的基本语法
变量
在R中,变量和赋值是基本的编程操作之一,涉及到数据的存储和管理.以下是对R中变量和赋值的详细介绍:
变量
变量定义:
- 创建变量:在R中,变量是通过赋值操作创建的.变量名可以由字母,数字和下划线组成,但不能以数字开头.
- 示例:
rx <- 10 name <- "Alice" is_valid <- TRUE
变量名规则:
- 有效字符:变量名必须以字母或点
.
开头,后面可以跟字母,数字或下划线_
.- 大小写敏感:R中的变量名是大小写敏感的.
myVar
和myvar
被视为不同的变量.- 命名习惯:变量名通常采用有意义的名称,并避免使用保留字(如
if
,else
,while
等).赋值操作
赋值运算符:
<-
:这是R中最常用的赋值操作符,用于将值赋给变量.例如:rx <- 5
=
:也可以用于赋值,尤其是在函数调用中.例如:rx = 5
->
:这是另一种赋值形式,将值赋给变量在右侧.例如:r5 -> x
赋值示例:
- 基本赋值:
rage <- 30 name <- "John"
- 多个赋值:
rx <- y <- z <- 10 # x, y, z 都被赋值为 10
变量的类型
基本数据类型:
数值型(Numeric):包含整数和浮点数.例如:
rnum1 <- 42 # 整数 num2 <- 3.14 # 浮点数
字符型(Character):字符串.例如:
rstr <- "Hello, R!"
逻辑型(Logical):布尔值
TRUE
或FALSE
.例如:rflag <- TRUE
复合数据类型:
- 向量(Vector):一维数据集合.例如:
rvec <- c(1, 2, 3, 4)
- 矩阵(Matrix):二维数据集合.例如:
rmat <- matrix(1:6, nrow=2, ncol=3)
- 列表(List):可以包含不同类型的数据.例如:
rlst <- list(name="Alice", age=25, scores=c(90, 80, 85))
- 数据框(Data Frame):表格数据结构,类似于数据库表或Excel表.例如:
rdf <- data.frame(name=c("John", "Jane"), age=c(28, 30))
变量的作用域
全局变量:在R脚本或R会话的顶层定义的变量,作用于整个脚本或会话.
rglobal_var <- 100
局部变量:在函数内部定义的变量,仅在函数内部有效.
rmy_function <- function() { local_var <- 50 return(local_var) }
环境(Environment):R中的变量也存在于不同的环境中,如全局环境,函数环境等.可以使用
ls()
和environment()
函数来查看和管理这些环境.赋值和引用
引用行为:
- 复制行为:在R中,赋值操作通常会创建一个新的对象(复制),尤其是在数据量较大的情况下.R通过"延迟复制"技术(copy-on-modify)优化性能,即只有在对象被修改时才进行实际复制.
内存管理:
- 垃圾回收:R使用垃圾回收机制来自动管理内存,回收不再使用的对象.
在R中,复合数据类型包括向量,矩阵,列表和数据框.每种数据类型都有不同的访问方式.以下是对每种复合数据类型的详细访问方式的介绍:
1. 向量(Vector)
创建向量:
rvec <- c(10, 20, 30, 40, 50)
访问元素:
- 按位置访问:
rvec[1] # 访问第一个元素,结果是 10 vec[3] # 访问第三个元素,结果是 30
- 按逻辑条件访问:
rvec[vec > 25] # 访问所有大于25的元素,结果是 30, 40, 50
- 按名称访问:如果向量有命名元素,可以通过名称访问:
rnamed_vec <- c(a=1, b=2, c=3) named_vec["b"] # 结果是 2
2. 矩阵(Matrix)
创建矩阵:
rmat <- matrix(1:9, nrow=3, ncol=3)
访问元素:
- 按位置访问:
rmat[1, 2] # 访问第一行第二列的元素,结果是 4
- 按行列访问:
rmat[1, ] # 访问第一行,结果是 1 4 7 mat[, 2] # 访问第二列,结果是 4 5 6
- 按逻辑条件访问:
rmat[mat > 5] # 访问所有大于5的元素,结果是 6 7 8 9
3. 列表(List)
创建列表:
rlst <- list(name="Alice", age=30, scores=c(85, 90, 95))
访问元素:
- 按名称访问:
rlst$name # 结果是 "Alice" lst$age # 结果是 30
- 按位置访问:
rlst[[1]] # 结果是 "Alice" lst[[3]] # 结果是 c(85, 90, 95)
- 按名称访问(替代方式):
rlst[["name"]] # 结果是 "Alice"
访问嵌套列表:
rnested_lst <- list(info=list(name="Bob", age=25), scores=c(70, 80, 90)) nested_lst$info$name # 结果是 "Bob" nested_lst[["info"]][["age"]] # 结果是 25
4. 数据框(Data Frame)
创建数据框:
rdf <- data.frame(name=c("John", "Jane"), age=c(28, 30), score=c(85, 90))
访问元素:
- 按列访问:
rdf$name # 访问name列,结果是 c("John", "Jane") df[["age"]] # 访问age列,结果是 c(28, 30)
- 按行列访问:
rdf[1, ] # 访问第一行,结果是 name="John", age=28, score=85 df[, 2] # 访问第二列(age列),结果是 c(28, 30) df[1, 2] # 访问第一行第二列的元素,结果是 28
- 按逻辑条件访问:
rdf[df$age > 28, ] # 访问age大于28的所有行
1. 按照逻辑条件访问多个变量的返回方式
当你使用逻辑条件访问多个变量时,返回的结果通常是一个向量,矩阵,列表或数据框,具体取决于你访问的数据结构.你可以将这些结果解包并赋值给多个变量,但需要使用适当的方式来处理不同类型的返回对象.
向量
对于向量,逻辑条件访问返回一个包含符合条件的元素的子向量:
rvec <- c(1, 2, 3, 4, 5) result <- vec[vec > 3] # 返回 c(4, 5)
可以将结果解包并赋值给多个变量:
rx <- vec[1] y <- vec[2]
但要确保你知道返回结果的长度和结构.
数据框
对于数据框,逻辑条件访问返回一个子数据框:
rdf <- data.frame(name=c("John", "Jane"), age=c(28, 30), score=c(85, 90)) result <- df[df$age > 28, ]
将结果解包到多个变量的一个常见方法是使用列提取:
rnames <- result$name ages <- result$age scores <- result$score
2. 使用嵌套的中括号在列表和数据框中
列表(List)
==在列表中,单个中括号
[]
返回一个子列表,而双重中括号[[]]
返回列表中的具体元素:==
单个中括号:
rlst <- list(a=1, b=2, c=3) sublist <- lst[1:2] # 返回子列表,包含lst的前两个元素
sublist
结果是list(a=1, b=2)
,它仍然是一个列表.双重中括号:
relement <- lst[[1]] # 返回第一个元素,结果是1
数据框(Data Frame)
==在数据框中,单个中括号
[]
用于按行和列访问数据(返回数据框),而双重中括号[[]]
用于访问单列并将其作为向量返回:==
单个中括号:
rdf <- data.frame(name=c("John", "Jane"), age=c(28, 30)) sub_df <- df[1:1, ] # 访问第一行,结果是一个数据框
sub_df
结果是data.frame(name="John", age=28)
.双重中括号:
rcolumn <- df[[1]] # 返回第一列,结果是向量 c("John", "Jane")
层级关系
列表:列表可以嵌套其他列表,向量,数据框等,形成多层结构.例如,
nested_lst <- list(a=1, b=list(c=2, d=3))
,其中b
是一个包含两个元素(c
和d
)的子列表.数据框:数据框的每一列可以视为一个向量(或列表),当使用单个中括号访问时,可以获得包含多个列的数据框;当使用双重中括号时,通常用于提取单列数据作为向量.
总结
- 按照逻辑条件访问:可以返回向量,矩阵,列表或数据框.解包赋值时要考虑返回结果的结构.
- 嵌套中括号:在列表中,单中括号返回子列表,双中括号返回具体元素;在数据框中,单中括号用于按行列访问,双中括号用于提取单列数据.不同的数据结构通过这些中括号操作提供了不同层级的数据访问能力.
总结
在R中,复合数据类型的访问方式因类型而异:
- 向量:可以按位置,逻辑条件或名称访问.
- 矩阵:可以按行列位置或逻辑条件访问.
- 列表:可以按名称,位置,或多层嵌套访问.
- 数据框:可以按列名,行列位置,或逻辑条件访问.
- ==使用逻辑条件访问的对象返回的是一个源对象数据类型的变量==
运算符
1. 算术运算符
- 加法:
+
R3 + 2 # 返回5
- 减法:
-
R3 - 2 # 返回1
- 乘法:
*
R3 * 2 # 返回6
- 除法:
/
R3 / 2 # 返回1.5
- 取余:
%%
R7 %% 2 # 返回1
- 整除:
%/%
R7 %/% 2 # 返回3
- 幂运算:
^
R3 ^ 2 # 返回9
2. 逻辑运算符
- 与:
&
(元素级)或&&
(仅检查第一个元素)RTRUE & FALSE # 返回FALSE TRUE && FALSE # 返回FALSE
- 或:
|
(元素级)或||
(仅检查第一个元素)RTRUE | FALSE # 返回TRUE TRUE || FALSE # 返回TRUE
- 非:
!
R!TRUE # 返回FALSE
3. 比较运算符
等于:
==
R3 == 3 # 返回TRUE
不等于:
!=
R3 != 2 # 返回TRUE
大于:
>
R3 > 2 # 返回TRUE
小于:
<
R3 < 2 # 返回FALSE
大于等于:
>=
R3 >= 2 # 返回TRUE
小于等于:
<=
R3 <= 2 # 返回FALSE
4. 赋值运算符
- 左赋值:
<-
或=
Rx <- 5 # 将5赋值给x y = 3 # 将3赋值给y
- 右赋值:
->
R10 -> z # 将10赋值给z
5. 特殊运算符
序列生成:
:
R1:5 # 生成序列1, 2, 3, 4, 5
元素在集合中:
%in%
R3 %in% c(1, 2, 3) # 返回TRUE
6. 条件语句
- if-else:
Rx <- 5 if (x > 3) { print("x大于3") } else { print("x不大于3") }
7. 循环语句
for循环:
Rfor (i in 1:5) { print(i) }
while循环:
Ri <- 1 while (i <= 5) { print(i) i <- i + 1 }
8. 函数定义
- function:
Radd <- function(a, b) { return(a + b) } add(2, 3) # 返回5
代码格式和注释
在R语言中,良好的代码风格和注释习惯不仅有助于提高代码的可读性,还能让你的代码在合作开发时更加易于维护和理解.以下是关于R语言注释和代码风格的一些建议和规范.
1. 注释(Comments)
单行注释
- 使用
#
来添加单行注释.#
后面的内容将不会被执行.- 注释应简洁明了,解释代码的逻辑或特殊的实现细节.
R# 这是一个单行注释 x <- 10 # 这是变量 x 的赋值
多行注释
- R中没有直接支持多行注释的语法,但可以通过多次使用
#
实现多行注释.R# 这是第一行注释 # 这是第二行注释 # 这是第三行注释
2. 代码风格(Code Style)
2.1 缩进与空格
- 缩进: 使用2个空格进行缩进.避免使用制表符 (
Tab
) 进行缩进.Rif (x > 0) { print("x大于0") } else { print("x小于等于0") }
- 空格: 在操作符和关键词周围添加空格,提高代码可读性.
R# 推荐写法 y <- x + 2 # 不推荐写法 y<-x+2
2.2 函数定义
- 在函数名和参数列表之间不要加空格.
R# 推荐写法 my_function <- function(x, y) { return(x + y) } # 不推荐写法,在function和下一个括号之前不要有空格 my_function <- function (x, y) { return (x + y) }
2.3 长行换行
- 如果一行代码过长,尽量保持在80个字符以内,可以通过换行来提升可读性.换行时,将操作符放在新行的开头,并进行适当的缩进.
Rresult <- some_long_function_name(arg1, arg2, arg3, arg4, arg5)
2.4 命名规范
- 变量和函数名称: 使用小写字母,单词之间用下划线
_
或驼峰式(camelCase
)命名.推荐使用有意义的变量名,避免使用单个字母.R# 使用下划线命名法 my_variable <- 10 # 或使用驼峰式命名法 myVariable <- 10
- 常量: 通常使用全大写字母命名,单词间用下划线分隔.
RMAX_VALUE <- 100
2.5 分号与表达式分隔
- 在R中不必使用分号
;
作为行尾的结束符,尽量保持一行一条语句.如果在同一行有多条语句,可以使用分号分隔,但这通常不建议.R# 推荐写法 x <- 5 y <- 10 # 不推荐写法 x <- 5; y <- 10
3. 代码组织
3.1 代码块和函数
- 将相关的代码逻辑组织成函数,以提高代码的可重用性和可维护性.
Rcalculate_sum <- function(a, b) { return(a + b) }
3.2 文件结构
- 保持代码文件简洁.较长的代码可以分割成多个逻辑单元,每个文件只处理一个主要功能.
3.3 代码分组
- 使用空行将代码逻辑分组,使得代码阅读时更加清晰.
R# 数据初始化 x <- 10 y <- 20 # 计算结果 result <- x + y # 输出结果 print(result)
4. 文档化代码
- 使用
roxygen2
格式化函数文档注释,特别适用于开发包时.注释格式包括函数描述,参数说明,返回值等.R#' 计算两个数的和 #' #' @param a 第一个数 #' @param b 第二个数 #' @return 两个数的和 #' @examples #' calculate_sum(3, 4) calculate_sum <- function(a, b) { return(a + b) }
总结
- 注释: 尽量使注释清晰,简洁,并解释复杂或特殊逻辑.
- 代码风格: 规范的缩进,空格,命名以及代码结构有助于提高代码的可读性.
- 代码组织: 将代码逻辑组织成模块和函数,保持文件简洁.
养成良好的编写和注释习惯,会使你的代码在团队协作中更加易于理解和维护.
数据的读取和写入
先明确工作路径
getwd()
– 获取当前工作路径
setwd()
– 设置某个文件夹为当前工作路径读取文件(常用excel或是sav文件)
需要额为安装readxl或者haven包
install.package()
library()
– 调用已安装的包
read_excel("文件名", sheet = x)
read_sav()
在R语言中,
read.csv()
和write.csv()
是处理CSV(逗号分隔值)文件的两个重要函数.它们用于读取和导出数据,这在数据分析中非常常见.下面将详细讲述这两个函数的使用方法和常见参数.1. 从CSV文件读取数据:
read.csv()
基本用法
read.csv()
函数用于从CSV文件中读取数据,并将其导入为一个数据框(data.frame
).它的基本语法如下:Rdata <- read.csv(file, header = TRUE, sep = ",", stringsAsFactors = FALSE)
file
: 文件路径或URL,可以是相对路径或绝对路径.header
: 是否将文件的第一行作为列名.默认为TRUE
,即第一行是列名.sep
: 字段分隔符,默认为","
,即逗号分隔.stringsAsFactors
: 是否将字符串自动转换为因子类型.默认为TRUE
,但推荐设置为FALSE
以避免不必要的因子转换.示例
R# 读取本地的 CSV 文件 data <- read.csv("data.csv") # 如果第一行不是列名 data <- read.csv("data.csv", header = FALSE) # 从网络读取 CSV 文件 data <- read.csv("https://example.com/data.csv")
常用参数说明
file
: 指定要读取的文件路径或URL.Rdata <- read.csv("C:/Users/Username/Documents/data.csv")
header
: 如果CSV文件没有列名,可以将header
设置为FALSE
.Rdata <- read.csv("data.csv", header = FALSE)
sep
: 如果你的CSV文件使用的不是逗号,而是其他分隔符,如分号,可以使用此参数指定分隔符.Rdata <- read.csv("data_semicolon.csv", sep = ";")
stringsAsFactors
: 默认情况下,read.csv()
会将字符串转换为因子类型,但如果不需要,可以将其设为FALSE
.Rdata <- read.csv("data.csv", stringsAsFactors = FALSE)
处理缺失值
na.strings
: 用于指定文件中哪些字符表示缺失值(NA
).例如,如果文件中缺失值用""
表示,可以这样设置:Rdata <- read.csv("data.csv", na.strings = "")
2. 数据的导出:
write.csv()
基本用法
write.csv()
函数用于将数据框导出为CSV文件.它的基本语法如下:Rwrite.csv(data, file, row.names = TRUE)
data
: 要导出的数据框.file
: 文件路径,指定导出文件的路径和名称.row.names
: 是否导出行名.默认值为TRUE
,即导出行名.示例
R# 导出数据到本地 CSV 文件 write.csv(data, "output.csv") # 不导出行名 write.csv(data, "output.csv", row.names = FALSE)
常用参数说明
file
: 指定要保存的文件路径,可以是相对路径或绝对路径.Rwrite.csv(data, "C:/Users/Username/Documents/output.csv")
row.names
: 控制是否导出行名.默认情况下,行名会作为第一列导出,如果不需要行名,可以将其设为FALSE
.Rwrite.csv(data, "output.csv", row.names = FALSE)
na
: 指定导出文件中缺失值的表示方式.默认值为"NA"
,但可以自定义缺失值符号.Rwrite.csv(data, "output.csv", na = "")
追加数据到CSV文件
如果需要将数据追加到现有CSV文件中,可以通过
append
参数控制文件的写入模式.Rwrite.csv(data, "output.csv", append = TRUE, row.names = FALSE)
3. 注意事项
- 文件路径: 在读取或写入文件时,请确保提供的路径是正确的.如果是相对路径,文件应位于当前工作目录中.如果不确定工作目录,可以使用
getwd()
函数查看,或者使用setwd()
更改工作目录.- 数据类型: 导入数据时要注意数据的类型.默认情况下,
read.csv()
会将字符串转换为因子.为避免这种情况,建议将stringsAsFactors = FALSE
,然后手动转换所需的列类型.总结
read.csv()
: 主要用于从CSV文件中读取数据,常见参数包括header
,sep
,stringsAsFactors
等.write.csv()
: 主要用于将数据导出到CSV文件,常见参数包括row.names
,na
等.通过这些函数,R语言能够方便地处理CSV格式的数据,便于数据的导入和导出.
在R语言中,
read.table()
和write.table()
是用于读取和写入表格数据的基础函数.这些函数非常灵活,可以处理各种分隔符的文本文件,不仅限于CSV格式.以下是这两个函数的详细介绍.
read.table()
read.table()
用于从文本文件中读取数据,并将其导入为一个数据框(data.frame
).它的基本语法如下:Rdata <- read.table(file, header = FALSE, sep = "", quote = "\"", dec = ".", fill = FALSE, comment.char = "", stringsAsFactors = TRUE)
主要参数说明
file
: 要读取的文件路径或URL.
header
: 是否将文件的第一行作为列名.默认为FALSE
,即文件的第一行不作为列名.Rdata <- read.table("data.txt", header = TRUE)
sep
: 字段分隔符.默认为空字符串""
,这意味着文件中的列由任意数量的空白字符(空格或制表符)分隔.你可以指定其他分隔符(如逗号","
,分号";"
).Rdata <- read.table("data.txt", sep = ",")
quote
: 用于引用的字符,通常是引号("
).用来指定哪些字符会被视为字符串的引号.
是的,
quote
参数在read.table()
和write.table()
中用于处理字符串数据的引号.在文本数据的读取和写入过程中,quote
参数的作用是确定如何识别和处理字符串.
quote
参数的作用 在
read.table()
中 在
read.table()
中,quote
参数用于指定哪些字符被视为字符串的引号.它帮助函数正确地识别文本文件中的字符串数据,即哪些部分需要被视为单个字符串.
- 默认值:
quote = "\""
, 这表示引号字符("
)用于界定字符串.- 其他值: 你可以设置
quote
为其他字符(例如,quote = "'"
),以指定不同的引号字符,或将quote
设置为空字符串""
来禁用引号处理.示例
假设你的数据文件
data.txt
内容如下:id,name,age 1,"John Doe",30 2,"Jane Smith",25
**
quote = "\""(默认值)**: 这会正确处理引号内的字符串
"John Doe"和
"Jane Smith"`,将它们识别为单个字符串值.Rdata <- read.table("data.txt", header = TRUE, sep = ",")
quote = ""
: 如果设置quote = ""
,那么所有的引号都不会被视为字符串的分隔符.这意味着引号内的内容会被当作普通文本处理,可能导致解析错误.Rdata <- read.table("data.txt", header = TRUE, sep = ",", quote = "")
在
write.table()
中 在
write.table()
中,quote
参数用于决定是否将字符串数据用引号括起来.当quote = TRUE
时,字符串会被引号括起来;当quote = FALSE
时,字符串不会被引号括起来.
- 默认值:
quote = TRUE
, 这表示将字符串用引号括起来.这个设置有助于防止数据中的分隔符被误解为列分隔符.示例
假设有一个数据框
data
如下:Rdata <- data.frame( id = 1:2, name = c("John Doe", "Jane Smith"), age = c(30, 25) )
`quote = TRUE(默认值): 导出时,字符串数据将用引号括起来.
Rwrite.table(data, "output.txt", sep = ",", quote = TRUE)
输出文件
output.txt
:"id","name","age" "1","John Doe","30" "2","Jane Smith","25"
quote = FALSE
: 导出时,字符串数据不会用引号括起来.Rwrite.table(data, "output.txt", sep = ",", quote = FALSE)
输出文件
output.txt
:id,name,age 1,John Doe,30 2,Jane Smith,25
总结
- 在
read.table()
中:quote
参数确定哪些字符用作字符串的引号,帮助函数正确解析文本数据.- 在
write.table()
中:quote
参数控制字符串是否被引号括起来,影响数据的导出格式.理解
quote
参数的作用有助于正确处理和导出文本数据,尤其是在字符串数据中包含分隔符或其他特殊字符时.Rdata <- read.table("data.txt", quote = "\"")
dec
: 小数点字符,默认为.
,用于指定小数点的表示方式.Rdata <- read.table("data.txt", dec = ",")
fill
: 是否在数据不齐全时填充缺失值.默认为FALSE
,即如果某行的列数与其他行不一致,则会产生错误.Rdata <- read.table("data.txt", fill = TRUE)
comment.char
: 用于指定注释字符,默认为""
(无注释字符).指定的字符后面的内容被视为注释,不会被读取.Rdata <- read.table("data.txt", comment.char = "#")
stringsAsFactors
: 是否将字符串转换为因子类型.默认为TRUE
,推荐设置为FALSE
以避免自动转换.Rdata <- read.table("data.txt", stringsAsFactors = FALSE)
示例
R# 读取一个以空格分隔的文本文件 data <- read.table("data.txt", header = TRUE, sep = " ") # 读取一个以逗号分隔的文本文件,并将字符串列保留为字符类型 data <- read.table("data.csv", header = TRUE, sep = ",", stringsAsFactors = FALSE)
write.table()
write.table()
用于将数据框写入到文本文件中.它的基本语法如下:Rwrite.table(x, file = "", row.names = TRUE, col.names = TRUE, sep = " ", quote = TRUE, na = "NA", append = FALSE, eol = "\n", dec = ".", qmethod = c("escape", "double"))
主要参数说明
x
: 要写入的对象,通常是数据框(data.frame
).
file
: 要写入的文件路径.如果省略,则会将数据写入到标准输出(控制台).
row.names
: 是否写入行名.默认为TRUE
.Rwrite.table(data, "output.txt", row.names = FALSE)
col.names
: 是否写入列名.默认为TRUE
.Rwrite.table(data, "output.txt", col.names = FALSE)
sep
: 字段分隔符,默认为空格" "
.可以指定其他分隔符(如逗号","
,分号";"
).Rwrite.table(data, "output.csv", sep = ",")
quote
: 是否对字符型数据进行引用.默认为TRUE
,即对字符型数据用引号括起来.Rwrite.table(data, "output.txt", quote = FALSE)
na
: 指定缺失值的表示方式.默认为"NA"
.Rwrite.table(data, "output.txt", na = "NULL")
append
: 是否将数据追加到现有文件中.默认为FALSE
,即覆盖现有文件.Rwrite.table(data, "output.txt", append = TRUE)
eol
: 行结束符,默认为换行符"\n"
.Rwrite.table(data, "output.txt", eol = "\r\n")
dec
: 小数点字符,默认为.
.Rwrite.table(data, "output.txt", dec = ",")
qmethod
: 指定如何处理引用字符.可以是"escape"
或"double"
.Rwrite.table(data, "output.txt", qmethod = "escape")
示例
R# 将数据框写入到一个以空格分隔的文本文件 write.table(data, "output.txt", sep = " ", row.names = FALSE, col.names = TRUE) # 将数据框写入到一个以逗号分隔的CSV文件 write.table(data, "output.csv", sep = ",", row.names = FALSE, col.names = TRUE)
总结
read.table()
: 用于从文本文件中读取数据.它支持多种分隔符和配置选项,可以处理不同格式的文本文件.write.table()
: 用于将数据框写入到文本文件.它提供了丰富的参数选项来控制数据的格式和文件的写入方式.这两个函数非常灵活,适用于各种数据处理任务,无论是读取还是导出文本数据.
数学函数
sqrt(6.25)
## [1] 2.5
exp(1)
## [1] 2.718282
log10(10000)
## [1] 4
# 不指定base则为e
log(8, base = 2)
## [1] 3
# 按照四舍五入保留两位小数
round(1.1234, 2)
## [1] 1.12
round(-1.9876, 2)
## [1] -1.99
# 向下取整
floor(1.1234)
## [1] 1
floor(-1.1234)
## [1] -2
# 向上取整
ceiling(1.1234)
## [1] 2
ceiling(-1.1234)
## [1] -1
# pi 表示圆周率 𝜋.sin 正弦, cos 余弦, tan 正切, 自变量以弧度为单位.
pi
## [1] 3.141593
sin(pi/6)
## [1] 0.5
cos(pi/6)
## [1] 0.8660254
tan(pi/6)
## [1] 0.5773503
# asin 反正弦, acos 反余弦, atan 反正切,结果以弧度为单位.
pi/6
## [1] 0.5235988
asin(0.5)
## [1] 0.5235988
acos(sqrt(3)/2)
## [1] 0.5235988
atan(sqrt(3)/3)
## [1] 0.5235988
dnorm(1.98)
## [1] 0.05618314
pnorm(1.98)
## [1] 0.9761482
qnorm(0.975)
## [1] 1.959964
在R语言中,
dnorm
,pnorm
和qnorm
是用于正态分布(也称为高斯分布)的三个常用函数.它们的用法如下:
dnorm(x, mean = 0, sd = 1, log = FALSE)
:
- 功能:计算给定点
x
处的正态分布密度函数(PDF)值.- 参数:
x
: 计算密度的数值点.mean
: 正态分布的均值,默认为0.sd
: 正态分布的标准差,默认为1.log
: 如果为TRUE,返回密度的对数值.- 示例:
dnorm(1.98)
计算标准正态分布在x = 1.98
处的密度值,结果为0.05618314
.
pnorm(q, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE)
:
- 功能:计算给定值
q
以下的累积概率,即累积分布函数(CDF)的值.- 参数:
q
: 累积概率的数值点.mean
: 正态分布的均值,默认为0.sd
: 正态分布的标准差,默认为1.lower.tail
: 如果为TRUE,计算从负无穷到q
的概率;如果为FALSE,计算从q
到正无穷的概率.log.p
: 如果为TRUE,返回概率的对数值.- 示例:
pnorm(1.98)
计算标准正态分布中x ≤ 1.98
的累积概率,结果为0.9761482
.
qnorm(p, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE)
:
- 功能:计算给定累积概率
p
所对应的分位数.- 参数:
p
: 给定的累积概率.mean
: 正态分布的均值,默认为0.sd
: 正态分布的标准差,默认为1.lower.tail
: 如果为TRUE,表示计算从负无穷到分位数的概率为p
;如果为FALSE,表示计算从分位数到正无穷的概率为p
.log.p
: 如果为TRUE,p
为概率的对数值.- 示例:
qnorm(0.975)
计算标准正态分布中累积概率为0.975
对应的分位数,结果为1.959964
.简而言之:
dnorm
计算密度值,即给定x
的点在正态分布下的可能性.pnorm
计算累积概率,即从左侧到给定x
的累积概率.qnorm
计算分位数,即给定概率p
所对应的x
值.
- ==需要学习==
- PDF (概率密度函数)给出的是密度值,公式依赖于均值和标准差.
- CDF (累积分布函数)给出的是累积概率,涉及误差函数.
- **QF ** (分位数函数) 是CDF的逆函数,用来找分位点,通常通过查表或数值方法求解.
函数的调用方式
R中调用函数, 与调用数学函数的规则相近, 如
sqrt(1.44)
. 有些函数允许有可选参数, 比如,round(1.2345)
结果是四舍五入取整, 加选项round(1.2345, digits=2)
结果则变成四舍五入到两位小数精度.复合函数的调用也与数学中用法类似, 如
log(exp(1.0))
表示:rlog(exp(1.0)) ## [1] 1
另外, R还提供了另外一种复合函数的调用格式:
rexp(1.0) |> log() ## [1] 1
其中的==运算符
|>
==称为管道运算符, 这种语法在复合函数有多层调用时更简明易读, 将每次调用函数看成对自变量的加工, 加工完以后通过管道传送给下一道工序加工, 如f3(f2(f1(x)))
写成x |> f1() |> f2() |> f3()
就更容易看清楚数据的流向.R支持自定义函数, 比如, 将一个复杂的计算表达式封装在函数定义中:
rx <- 1 frat <- function(x){ (1 + x + 2*x^2)/(1 + 3*x + 2*x^2 + x^3) } y <- (x |> frat()) print(y)
定义中最后一个语句的结果作为函数输出, 也可以用
return(y)
输出变量y
的值.自定义函数的好处是一次定义可以反复使用, 而且函数内用的变量不会与其它变量造成混杂干扰.
输出
简单输出
命令行的计算结果直接显示在命令的后面.==只能是单个数据,否则会报错==
在用
source()
运行程序文件时, 需要用print()
函数显示一个表达式的结果,如:rprint(sin(pi/2)) ## [1] 1
用
cat()
函数显示多项内容, 包括数值和文本, 文本包在两个单撇号或两个双撇号中(==可以交替使用,避免转义字符==),如:rcat("sin(pi/2)=", sin(pi/2), "\n") ## sin(pi/2)= 1
cat()
函数最后一项一般是"\n"
, 表示换行. 忽略此项将不换行.再次提示:要避免打开中文输入法导致误使用中文标点.
用
sink()
函数作运行记录 R使用经常是在命令行逐行输入命令(程序), 结果紧接着显示在命令后面. 如何保存这些命令和显示结果?
在R命令行中运行过的命令会被保存在运行的工作文件夹中的一个名为
.Rhistory
的文件中. 用sink()
函数打开一个文本文件开始记录文本型输出结果. ==结束记录时用空的sink()
即可关闭文件不再记录.== 如rsink("tmpres01.txt", split=TRUE) print(sin(pi/6)) print(cos(pi/6)) cat("t(10)的双侧0.05分位数(临界值)=", qt(1 - 0.05/2, 10), "\n") sink()
sink()
用作输出记录主要是在测试运行中使用, 正常的输出应该使用cat()
函数,write.table()
,write.csv()
等函数.
向量
4.2 向量运算
4.2.1 标量和标量运算
单个数值称为标量, R没有单独的标量类型, 标量实际是长度为1的向量.
R中四则运算用
+ - * / ^
表示(加,减,乘,除,乘方),如r1.5 + 2.3 - 0.6 + 2.1*1.2 - 1.5/0.5 + 2^3 ## [1] 10.72
R中四则运算仍遵从通常的优先级规则, 可以用圆括号
()
改变运算的先后次序. 如r1.5 + 2.3 - (0.6 + 2.1)*1.2 - 1.5/0.5 + 2^3 ## [1] 5.56
除了加,减,乘,除,乘方, R还支持整除运算和求余运算. 用
%/%
表示整除,用%%
表示求余.如r5 %/% 3 ## [1] 1 5 %% 3 ## [1] 2 5.1 %/% 2.5 ## [1] 2 5.1 %% 2.5 ## [1] 0.1
4.2.2 向量与标量运算
向量与标量的运算为每个元素与标量的运算, 如
rx <- c(1, 10) x + 2 ## [1] 3 12 x - 2 ## [1] -1 8 x * 2 ## [1] 2 20 x / 2 ## [1] 0.5 5.0 x ^ 2 ## [1] 1 100 2 / x ## [1] 2.0 0.2 2 ^ x ## [1] 2 1024
一个向量乘以一个标量, 就是线性代数中的数乘运算.
四则运算时如果有缺失值,缺失元素参加的运算相应结果元素仍缺失. 如
rc(1, NA, 3) + 10 ## [1] 11 NA 13
4.2.3 等长向量运算
等长向量的运算为对应元素两两运算. 如
rx1 <- c(1, 10) x2 <- c(4, 2) x1 + x2 ## [1] 5 12 x1 - x2 ## [1] -3 8 x1 * x2 ## [1] 4 20 x1 / x2 ## [1] 0.25 5.00
两个等长向量的加,减运算就是线性代数中两个向量的加,减运算.
4.2.4 不等长向量的运算
两个不等长向量的四则运算, 如果其长度为倍数关系,规则是每次从头重复利用短的一个. 如
rx1 <- c(10, 20) x2 <- c(1, 3, 5, 7) x1 + x2 ## [1] 11 23 15 27 x1 * x2 ## [1] 10 60 50 140
不仅是四则运算,R中有两个或多个向量按照元素一一对应参与某种运算或函数调用时, 如果向量长度不同,一般都采用这样的规则.
**如果两个向量的长度不是倍数关系,会给出警告信息.**如
rc(1,2) + c(1,2,3) ## Warning in c(1, 2) + c(1, 2, 3): longer object length is not a multiple of ## shorter object length ## [1] 2 4 4
4.3 向量函数
4.3.1 向量化的函数
R中的函数一般都是向量化的: 在R中, 如果普通的一元函数以向量为自变量,一般会对每个元素计算. 这样的函数包括sqrt, log10, log, exp, sin, cos, tan等许多. 如
rsqrt(c(1, 4, 6.25)) ## [1] 1.0 2.0 2.5
为了查看这些基础的数学函数的列表,运行命令
help.start()
, 点击链接"Search Engine and Keywords", 找到"Mathematics"栏目, 浏览其中的"arith"和"math"链接中的说明. 常用的数学函数有:
- 舍入:
ceiling
,floor
,round
,signif
,trunc
,zapsmall
- 符号函数
sign
- 绝对值
abs
- 平方根
sqrt
- 对数与指数函数
log
,exp
,log10
,log2
- 三角函数
sin
,cos
,tan
- 反三角函数
asin
,acos
,atan
,atan2
- 双曲函数
sinh
,cosh
,tanh
- 反双曲函数
asinh
,acosh
,atanh
有一些不太常用的数学函数:
- 贝塔函数
beta
,lbeta
- 伽玛函数
gamma
,lgamma
,digamma
,trigamma
,tetragamma
,pentagamma
- 组合数
choose
,lchoose
- 富利叶变换和卷积
fft
,mvfft
,convolve
- 正交多项式
poly
- 求根
polyroot
,uniroot
- 最优化
optimize
,optim
- Bessel函数
besselI
,besselK
,besselJ
,besselY
- 样条插值
spline
,splinefun
- 简单的微分
deriv
如果自己编写的函数没有考虑向量化问题, 可以用
Vectorize()
函数将其转换成向量化版本.