R语言试题背后的数据思维:数据类型、对象结构与统计基础 简介这份《R试题附带答案》文档面向准备R语言课程考试、面试复习或基础自测的学习者以题目加答案解析的形式梳理描述性统计与推断性统计、名义/有序/计数/计量数据类型以及工作目录查看、head()、ls()、rm()等入门操作。内容还覆盖向量运算、因子创建、矩阵构造与索引、apply类函数应用等常见考点每题附有答案便于对照排查知识盲区。压缩包共1个docx文件约96KB轻量易取适合打印练习或在电脑端逐题核对。已有11252人学习下载说明其题目覆盖面与解析方式具有一定参考价值。读者可借此完成一次从概念辨析到代码输出的系统自测尤其适合考前快速过一遍基础语法、函数返回值与易错细节也可作为课堂练习或复习提纲的补充材料。1. R语言试题到底在考什么一张卷子背后的一套数据思维学车前要考科目一全是选择题很多人背完就忘觉得没啥用。真上了路才发现那些看着死板的判断题决定了你在路口会不会下意识踩错踏板。R语言试题也是这个性质它不教你怎么写出漂亮的分析脚本而是把「这段代码为什么报错」「结果为什么和我手算的不一样」拆成一道道选择题逼你把判断做对。这份资料是一套带答案的R语言试题从最基础的名词描述性统计、推断性统计、名义数据、计量数据一路考到R的对象结构、控制流、自定义函数、描述性统计图形、常见概率分布和参数估计。它值得花时间搞懂的理由很朴素R的报错绝大多数不是算法错而是类型判断错、结构判断错、下标算错——恰好就是卷子上反复出现的那几个坑。2. 从「学历」和「身高」说起四种数据类型为什么决定了后面所有操作2.1 名义、有序、计数、计量两组划分先把数据分完统计学里给数据分类用的是两刀切。第一刀切出「定性」和「定量」定性数据描述的是类别定量数据描述的是数量。第二刀再各自细分——定性数据分成名义数据和有序数据定量数据分成计数数据和计量数据。这套划分听着像背书其实每个名字都在回答一个问题这个数字能不能做算术。名义数据是最「弱」的一档。它用数字或文字标记身份但数字本身没有大小含义。比如一家公司里1代表行政部、2代表财务部、3代表销售部这里的1和3之间不存在「3比1多两倍」这回事把三个部门编码加起来等于6毫无意义。有序数据比它强一点类别之间有明确顺序但相邻两档之间的差距不一定相等比如满意度分成「不满意、一般、满意」你知道满意高于一般却说不清高多少。计数数据是一颗一颗数出来的只能是整数比如某门店一天卖出的手机台数、某路段一小时通过的车次。计量数据是量出来的可以有小数比如身高、体重、温度。区分这两个的办法很直接问一句「这个数能不能出现0.5」。卖手机不能说卖了3.5台但身高可以说1.75米。提示判断数据类型时不要去纠结数字长什么样只问一句「对它做加减乘除有没有现实意义」。有意义是定量没意义是定性。2.2 为什么数据类型是R的「身份证」R在运行时并不看你给变量起了什么名字它看的是这个对象身上挂着的类型标记。同样一个1存成数值就是数值存成字符就是字符两者的行为完全不同数值能求和字符求和直接报错。这一点在试卷里有个特别典型的题x - 3 y - as.character(x) y is.numeric(y)运行结果是[1] 3 [1] FALSE前半段输出的3带着引号说明它已经是字符了后半段is.numeric()返回FALSE是在确认这个事实。很多人会本能地觉得「3不就是数字吗」这正是类型概念最容易绊人的地方——值看起来一样身份已经换了。转换之后y 1会报错而不是得到4。理解了这层就能看懂试卷里另一道题为什么要考L - 3 5。是一个比较运算符它不赋值数字只回答是或否所以L是逻辑变量值为FALSE。这里还藏着一个新手常踩的坑R里判断相等用两个等号一个等号是赋值。写成L - 3 5直接就是语法错误。2.3 描述性统计和推断性统计一条线划开两半试卷第一题问「用图或表描述数据属于什么」答案是描述性统计。第二题紧接着问统计学分成哪两部分答案是描述性统计和推断性统计。这两道题挨在一起不是凑数它们划的是整门课的分界线。描述性统计做的事是把手上这堆数据压缩成几个能看懂的数字或图形平均数、方差、频数表、直方图。它只对你手里的样本负责不往外推。推断性统计做的事正好相反它拿样本去猜总体用一小部分信息去推未知的全貌代价是要承担犯错的风险所以才有置信区间、显著性水平这些概念的用武之地。打个比方描述性统计像体检报告——血压多少、心率多少白纸黑字写清楚推断性统计像医生看完报告后说「你大概率没什么问题」这句话有依据但不是百分之百确定。两者用的是同一批数据承担的责任完全不同。3. R的对象家族向量、矩阵、数组、列表、数据框到底差在哪3.1 向量R里最小的积木循环补齐是它的隐藏规则向量是同类型元素排成的一队。R里几乎所有运算都是按向量设计的这也是它和很多语言最不一样的地方——你写c(1, 2, 3) * 2得到的是每个元素各乘2不需要写循环。当两个长度不同的向量做运算时R会启动「循环补齐」短的自动重复自己直到长度对上。试卷里那道题就是在考这个c(1, 2, 3, 4, 5) c(20, 200) # 短向量循环成 20 200 20 200 20逐位相加 # 结果[1] 21 202 23 204 25注意这里没有报错。R不会因为长度不整除就停下来它只会给一条警告warning然后照算不误。这个设计的初衷是方便做批量运算可一旦你没意识到它在补齐结果就会莫名其妙。比如你以为自己在做两组的对应相加实际上第二组被重复使用了两遍半。真正会报错的情况是长度不成整数倍比如长度5加长度25不是2的倍数R会给警告说长的对象长度不是短的对象长度的倍数但仍然返回结果。要判断代码是不是踩了补齐最稳的办法是在关键步骤打印length()核对一下。3.2 矩阵与数组给向量加一层「格子」矩阵就是二维的、同类型的表格。R里创建矩阵最常用的函数是matrix()它有一个默认行为必须记住按列填充。# 12个数3行默认按列填 A - matrix(1:12, nrow 3) A # [,1] [,2] [,3] [,4] # [1,] 1 4 7 10 # [2,] 2 5 8 11 # [3,] 3 6 9 12如果想让数字横着排得显式加一句byrow TRUE。这个参数是新手最容易漏的漏了之后矩阵转置了却浑然不觉后面所有取子集的操作全跟着错。试卷里有一道题问要生成上面这个矩阵可以用哪些写法答案是array(1:12, c(3, 4))、A - 1:12; dim(A) - c(3, 4)、matrix(1:12, nrow 3)、matrix(1:12, nrow 3, ncol 4)、array(1:12, dim c(3, 4))全都行。这五个写法之所以等价是因为它们本质上都在做同一件事——给一维的12个数挂上一个维度属性。dim()不是创建新对象而是给已有对象贴标签贴完之后R就把它当矩阵对待了。取子集用方括号加行列位置逗号左边是行、右边是列留空表示「全要」A[2:3, c(3, 4)] # 第2、3行 与 第3、4列交叉的部分 # [,1] [,2] # [1,] 8 11 # [2,] 9 12 A[, 1] # 第一列全部返回的是一个向量 # [1] 1 2 3这里的分寸感很重要只取一列时结果降维成向量不再是矩阵。想保住矩阵结构得加drop FALSE。这个细节在后面做数据框操作时会反复出现。3.3 列表与数据框允许「混装」的两个盒子矩阵有个硬性要求所有元素类型一致。可现实数据从来不是这样的——一列是姓名字符一列是年龄数值一列是部门因子。这时候就需要能装不同东西的容器。列表是最宽松的容器里面什么都能塞向量、矩阵、因子、甚至另一个列表。取元素用双方括号[[ ]]取出来的是元素本身用单方括号[ ]取出来的还是一个列表。数据框本质上就是一个被规整过的列表每一列是一个向量所有列长度相等但列与列之间类型可以不同。这一点试卷里专门考过——矩阵要求元素类型一致数据框不要求因为它的列本质是向量一列内类型一致就够了列与列之间可以各管各的。这也是数据框能对应现实表格的原因一列姓名、一列年龄、一列性别本来就该是不同类型。数据框还有个隐形福利它给每一列起了名字所以可以用列名访问。df$Height、df[[Height]]、df[, Height]取出来都是向量而df[Height]取出来是只有一个列的数据框。差别看着小用错了后面全乱。3.4 索引取子集三种括号各管一件事R的括号长得像分工很清楚()是调用函数和改变运算优先级[]是取子集[[]]是从容器里掏出元素本身。这三者在列表和数据框上体现得最明显。还有一类下标容易被忽略负号表示排除。v - 10:5 # 10 9 8 7 6 5 v[-c(1, 5)] # 排除第1个和第5个剩 9 8 7 5 v[-(1:5)] # 排除前5个只剩 5负下标不能和正下标混用比如v[c(1, -2)]会直接报错。这条规则在选择题里出现频率不低因为很多人凭直觉以为负号是「倒着数」。另一个高频点是which()它返回的不是值是位置。which(2:8 5)先把2:8逐个和5比得到一串FALSE FALSE FALSE FALSE TRUE TRUE TRUEwhich()再把这串逻辑值里TRUE的位置挑出来返回5 6 7。所以它的结果永远可以用来当下标v[which(...)]这种写法就是这么来的。4. 常见误区这些题看着像送分其实最容易翻车4.1 误区一把编码当数字对名义数据求平均易混点部门编码1、2、3学历编码1、2、3看着都是数字就直接mean()。为什么混数据录入时为了省事类别全用数字代替存进R里天然就是数值型。函数不会拦你它老老实实把1、2、3加起来除以3给你一个2——一个在现实中不存在的「平均部门」。怎么区分问自己这个数字做加法有没有意义。没有意义就必须在导入后立刻把它声明成因子factor(x, levels c(1, 2, 3), labels c(行政部, 财务部, 销售部))让R知道这是分类不是量。声明之后mean()会直接报warning并返回NA这就是R在替你踩刹车。4.2 误区二以为df[Height]和df$Height是一回事易混点三种取法写出来只差一两个符号结果一个是向量一个是数据框。为什么混很多语言里「取一列」只有一种结果R却给了两条路而且都不报错只是结构不同。等你把它传给mean()或者hist()才发现一个正常一个报错。怎么区分记住方括号里带逗号的、双层的掏出来的是内容本身单层方括号加列名切出来的仍是数据框的一片。判断办法是class()一下一眼就清楚。做图、做计算用向量需要保留表格结构往下传比如merge、subset时用数据框。4.3 误区三levels和labels当成可有可无的装饰易混点题目里「只想对1和2两个部门做分类统计」选项里有的写levels c(1, 2, 3)有的写levels c(1, 2)。为什么混两个参数都出现在factor()里看着像同义反复。怎么区分levels决定「哪些值算有效」labels决定「有效值显示成什么名字」。写levels c(1, 2)等于宣布3不是合法类别原本编码为3的行会被悄悄变成NA——这一步不会报错只会在你统计总数时发现少了一批人。想保留三类只是显示成两个名字levels就得写全三项。至于gl()那是专门用来生成规则因子序列的函数不是用来转换已有数据的选项里拿它冒充factor()是最常见的干扰项。4.4 误区四1:n-1和1:(n-1)分不清易混点冒号的优先级高于减号1:n-1会被解析成(1:n) - 1。为什么混数学书写习惯了「1到n-1」眼睛看到的就是这个意思可R不这么读。当n - 3时1:n-1先算出1 2 3再整体减1得到0 1 2开头多了一个0。怎么区分凡是冒号后面跟运算一律加括号。1:(n-1)才是想要的结果。这类错误不会报错只会让向量悄悄多一位或少一位然后在后续的下标引用里引发一连串错位属于典型的「当时看不出来事后查半天」。4.5 误区五四种平均数随手抓一个用易混点算术、加权、几何、调和四个都叫「平均数」。为什么混平时说「平均」默认就是加起来除以个数可有些场景这么算出来是错的而且错得不明显。怎么区分看分母是什么。分母是「个数」用算术平均分母是「权重」股数、学分、占比用加权平均变化率连乘、增长率求平均用几何平均给出的是「每单位对应的量」速度、单价而总量固定用调和平均。判断口诀是先想清楚你平均的到底是「每一份」还是「每一次」。试卷里那道「前半段时速60、后半段时速30两段距离相等」的题答案就是调和平均——因为时间是按距离反比分配的不能直接对两个速度取算术平均。同一道题如果改成「前半段开1小时、后半段开1小时」那就变成算术平均了。注意R里求中位数的函数是median()不是media()。少一个字母就是「找不到函数」的报错考卷上把它写成media()属于典型笔误实际敲代码时却真有人这么写。5. 描述性统计与概率分布平均数不止一种分布也不止一种5.1 定性数据的两套描述工具一张表、三张图定性数据没法求均值所以它的描述方式只有两条路数频数和画图。数频数用table()它返回每个类别出现了多少次。想看占比就再套一层prop.table()dept - factor(c(行政, 财务, 销售, 行政, 行政, 财务)) table(dept) # 各类别的绝对次数 prop.table(table(dept)) # 各类别的相对占比加起来等于1图形这边有三样条形图barplot()、饼图pie()、帕累托图。前两个好理解帕累托图其实就是把条形图按频数从高到低排序再叠一条累计占比曲线——它背后的经验法则是「少数类别贡献了大部分数量」用来快速找出重点。试卷里问定性数据的图形有哪几种答案就是条形图、饼图和帕累托图对应的函数是barplot()和pie()。5.2 定量数据的图形三件套直方图、茎叶图、箱线图定量数据可以画的图多得多但最基础的是三个直方图hist()看分布形状茎叶图stem()既看形状又保留原始数值箱线图boxplot()看中位数、四分位数和异常值。x - c(21, 8, 2, 5, 11) hist(x) # 分组看频数分布 stem(x) # 文本形式保留每个原始值 boxplot(x) # 五数概括 离群点标记三者的分工可以用一句话记住直方图告诉你「数据堆在哪儿」茎叶图告诉你「堆在那儿的到底是哪些数」箱线图告诉你「有没有人掉队」。样本量很小的时候茎叶图尤其好用因为它不丢信息样本量上千之后茎叶图会印满屏幕那就该换直方图了。5.3 四种平均数本质是「谁当分母」的问题平均数的选择不是数学游戏它取决于你手上拿的是什么口径的数据。加权平均最常见总评成绩就是典型平时占10%、实验作业占20%、期末占70%直接三项相加除以3是错的必须按权重乘完再除。股票的平均成本也是加权——买了1000股10元的、2000股15元的平均成本是(1000×10 2000×15) / 3000不是(1015)/2。后者的错误在于把「股数」这个真实权重抹平了。几何平均处理的是连乘关系。周一到周五的销售目标如果是在前一天基础上分别增长10%、12%、8%、11%、9%那平均增长率不是把这五个百分比加起来除以5而是把它们各自加1之后连乘、再开5次方、最后减1。原因是增长是叠在上一天的基础上发生的加法在这里会高估。调和平均处理的是「固定总量下的单位量」。同样花1元钱在三个市场买单价不同的水果问平均每千克多少钱答案是总钱数除以总重量而总重量是1/单价之和这就落到调和平均上了。同理两段等距离的路程求平均速度也是调和平均。提示拿不准的时候先写出「总量 ÷ 份数」这个原始式子再看份数是怎么来的。份数由权重决定就用加权由比率倒数决定就用调和由连乘决定就用几何。5.4 六个常见分布和它们的两把尺子试卷里反复出现的分布有六个分成离散和连续两组。离散组二项分布、泊松分布、超几何分布。二项分布描述n次独立重复试验里成功的次数期望是np方差是np(1-p)。泊松分布描述单位时间或单位空间内稀有事件发生的次数它有个漂亮的性质——期望和方差都等于λ。超几何分布和二项分布的关系是试卷爱考的二项分布对应有放回抽样每次试验条件不变超几何分布对应无放回抽样抽走一个总体就变了一点。样本量相对总体很小的时候两者结果几乎一样所以实际工作中常拿二项近似超几何。连续组均匀分布、正态分布、指数分布。均匀分布在区间[a, b]上概率密度处处相等期望是(ab)/2方差是(b-a)²/12——那个12是推导出来的常数不用记来源记住形式即可。正态分布由均值μ和方差σ²两个参数完全确定期望就是μ、方差就是σ²。指数分布的期望是1/λ方差是1/λ²。指数分布和泊松分布的关系值得单独说一句泊松描述的是「一段时间内事件发生几次」指数描述的是「两次事件之间隔多久」前者是计数后者是等待时间两者共用同一个λ但含义相反。某洗车店每小时平均来10辆车那么车辆到达的间隔就服从λ10的指数分布平均间隔是1/10小时也就是6分钟。这里最容易错的是把平均间隔写成10——λ是「单位时间多少次」取倒数才是「每次多久」。5.5 统计三大分布与抽样样本均值自己也有分布到这里还差一块拼图抽样分布。它的核心问题是——我从总体里抽n个样本算出一个均值这个均值本身会不会波动答案是会而且它自己服从一个分布。如果总体是N(μ, σ²)那么样本均值服从N(μ, σ²/n)。注意方差被除以了n这解释了一个日常经验样本量越大样本均值越稳定。n从100涨到400均值的标准差减半这也是为什么调查样本量翻四倍才能把误差压一半。由正态分布还能派生三个分布试卷称之为统计三大分布卡方分布、t分布、F分布。卡方分布是若干个标准正态变量的平方和常用来构造方差的区间估计t分布长得像正态但尾巴更厚专门用于总体方差未知时对均值做推断F分布是两个卡方分布各自除以自由度之后的比值用于比较两组方差。这三个分布是后面做假设检验的全部工具箱试卷把它们和「均匀、正态、指数」放在一起做干扰项就是要你分清哪些是描述数据的分布、哪些是描述统计量的分布。顺带提一句点估计。试卷问常见点估计方法有哪几种答案是矩估计法、极大似然估计法和最小二乘估计法。矩估计的思路最直白用样本矩去估计总体矩样本均值估总体均值、样本方差估总体方差拿已知推未知。6. 什么时候该刷这套题、什么时候别刷一份边界判断这套题的价值边界其实很清楚用一张表能说透。场景适不适合原因刚学完数据类型和对象结构想自查有没有概念漏洞适合题目密度高覆盖了名义/有序、向量/矩阵/列表/数据框这些最容易含混的点考试前想快速过一遍函数名和参数适合head、ls、rm、factor、apply、table、hist 这些高频函数几乎都出现了想搞懂某个函数背后的算法原理不适合卷子只给结论和答案不展开推导需要另找教材想做真实数据分析项目练手不适合题目都是碎片化的单点验证缺少完整的数据清洗到建模流程已经能熟练写R脚本只想查漏补缺部分适合可以只挑矩阵取子集、因子转换、apply 家族这几块看判断自己该不该刷有个简单办法随便挑一道题先别管答案把代码敲进控制台跑一遍看结果和你脑子里预判的是否一致。一致说明这块你已经过关可以跳过不一致那就是你要补的洞。这个自测方式比从头到尾刷一遍效率高得多因为你的时间应该花在「预判失败」的地方而不是「已经会」的地方。至于什么时候别刷我的建议是如果你连向量和列表都还分不清先别碰最后那几章的概率分布和参数估计。那部分题目默认你已经能熟练操作数据结构直接上手只会变成背答案。反过来如果你正在准备一场以选择题为主的考核这套题的性价比就很高——它把出题人爱设的陷阱都摊在明面上了比如循环补齐、单双方括号、levels截断、冒号优先级这些点看一遍答案记不住必须自己踩一次。我自己的习惯是每次遇到一段结果和预期不符的代码先不急着改而是把中间每一步的class()、length()、str()打出来看一遍。这个动作最早就是从做这类题养成的——当时错了一道df[Height]的题明明觉得取的就是那一列mean()却报错查了半天才发现拿到的是数据框不是向量。从那以后我每次写取子集的代码都会先跑一遍class()确认结构宁可多打一行也不让它在几十行之后才炸出来。希望这套题也能帮你把那些「以为懂了其实没懂」的地方提前暴露出来完整题目和答案都在资料里需要的话去下载页自取就好。本文还有配套的精品资源点击获取