R 中的数据类型
R 中的每个值都属于少数几种原子类型之一。其中四种承担了几乎所有工作:
- double:小数,如
3.14、-2、1e6。这就是 R 所说的“numeric”,你输入的任何数字默认都是它。 - integer:精确存储的整数,带
L后缀:42L。 - character:引号里的文本:
"hello"。 - logical:两个真值
TRUE和FALSE(还有表示缺失值的NA,见缺失值)。
还有 complex(2 + 3i),偶尔用于信号处理之类的数学计算;你可能好几年都用不上它。typeof() 会告诉你一个值属于哪种类型:
注意第一行:普通数字即使看起来是整数,也是 double。typeof(42) 是 "double",只有 42L 才是 integer。日常分析中这个区别很少有影响,因为 R 会在两者之间悄悄转换,但它能解释 typeof() 很多看似奇怪的输出。
typeof() 和 class():为什么答案不同
R 有两个函数看起来都在回答“这是什么?”,但它们回答的问题略有不同。
typeof()报告存储类型:值在内存中是怎么存放的。class()报告行为类型:R 的方法分派用这个标签来决定,比如该运行哪个print或summary。
对简单的值,两者的答案只是叫法不同:
typeof() 说 double(存储方式),class() 说 numeric(行为)。对结构来说,差别就更大了:
矩阵在存储上只是一个普通的整数向量,但它的行为是矩阵:正是 class() 让 R 把它打印成网格。数据框(typeof 说 "list",class 说 "data.frame")和日期(typeof 说 "double",class 说 "Date")也有同样的区别。
实用的规则:想知道一个东西在日常意义上“是什么”,用 class();想调试 R 在底层做了什么,用 typeof()。
用 is.*() 检查类型
每种类型都有对应的判断函数,返回 TRUE 或 FALSE,在需要校验输入的函数里很好用:
有个陷阱值得了解:is.numeric() 对 double 和 integer 都返回 TRUE(它们都是数字),但 is.integer() 检查的是存储方式,所以对普通的 42 返回 FALSE:
如果你曾经奇怪,为什么一个在数学上明明是整数的数,is.integer(7) 却是 FALSE,原因就在这里。7 是 double,7L 才是 integer。
用 as.*() 转换类型
显式转换用 as.* 系列函数,每种目标类型对应一个函数:
有两个行为要记住。as.integer() 是向零截断,而不是四舍五入:7.9 变成 7。另外,当转换没有意义时,R 不会报错,而是返回 NA 并发出警告:
运行它,你会看到 NA 和一条 “NAs introduced by coercion” 警告。这确实很有用:把一整列杂乱的文本转换成数字,无法解析的条目会变成 NA,而不是让脚本崩溃。但这也意味着一个不声不响的 NA 可能混进你的数据。当转换很重要时,事后检查一下有没有新出现的 NA。
逻辑值和数字之间的转换符合你的预期:as.numeric(TRUE) 是 1,as.logical(0) 是 FALSE。这就是为什么对逻辑向量求 sum() 能数出 TRUE 的个数:
隐式强制转换:向量只能有一种类型
R 中的原子向量只能保存一种类型。用 c() 组合不同类型的值时,R 会悄悄把所有元素提升为其中最通用的类型,顺序固定:
logical → integer → double → character
逻辑值变成了 1 和 0,整数变成了 double,而在最后一行,所有元素都变成了文本。character 总是胜出,因为任何值都能写成字符串。你可以用 typeof() 确认:
强制转换是“为什么我的列变成文本了?”这类 bug 的头号来源:一列数字里只要混进一个 "N/A" 字符串,整个向量就会被强制转换成 character。遇到这种情况,先修正出问题的值,再用 as.numeric() 转回来。
要点总结
- 四种主力类型:double(“numeric”)、integer(
42L)、character、logical。 typeof()看存储方式,class()看行为。3.14是一个表现为numeric的double。- 用
is.numeric()等函数检查类型,用as.numeric()等函数转换类型:转换失败会得到NA和一条警告,而不是报错。 - 向量只能保存一种类型;混合时按 logical → integer → double → character 的顺序强制转换。
下一篇:深入了解数值类型,包括取整、数学函数,以及所有编程语言都有的浮点数意外。
常见问题
R 的基本数据类型有哪些?
原子类型有 double(小数,R 称之为“numeric”)、integer(带 L 后缀的整数,如 42L)、character(引号里的文本)、logical(TRUE/FALSE),以及很少用到的 complex。更大的结构,比如向量、数据框、列表,都是由它们构成的。
R 中 typeof() 和 class() 有什么区别?
typeof() 报告值在内存中如何存储(底层类型);class() 报告值表现为什么,它决定 R 调用哪个方法。对普通小数,两者只是叫法不同:typeof(3.14) 是 "double",而 class(3.14) 是 "numeric"。对数据框这样的结构,typeof() 说 "list",class() 说 "data.frame"。
R 中怎么转换类型?
用 as.* 系列函数:as.numeric("3.5") 得到 3.5,as.character(42) 得到 "42",as.integer(7.9) 截断为 7。当转换无法完成时,R 返回 NA 并给出警告,而不是报错:as.numeric("abc") 的结果是 NA。
R 中的强制转换是什么?
当你在一个向量里混合不同类型时,R 会悄悄把所有元素转换成最通用的类型,顺序是 logical → integer → double → character。所以 c(1, 2, "three") 会变成字符向量:"1" "2" "three"。