map() 与类型化变体
使用 map()、map_dbl()、map_chr() 和 map_lgl() 对列表应用函数
map() 与类型化变体 是 CoddyKit 上的免费 R Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。
使用 purrr 进行函数式编程
purrr 包为 R 中的函数式编程提供了一致且类型安全的工具。您无需编写 for 循环,而是将一个函数映射到列表或向量的每个元素上。这样生成的代码更加简洁,也更易于理解和组合。
library(purrr)
# A list of numbers
numbers <- list(1, 4, 9, 16, 25)
# Apply sqrt() to each element
result <- map(numbers, sqrt)
print(result)map() — 始终返回列表
map(.x, .f) 会将函数 .f 应用于 .x 的每个元素,并返回一个列表。输入可以是列表、向量或数据框(此时会遍历各列)。这是最通用的 map 变体。
library(purrr)
# Map over a character vector
fruits <- c('apple', 'banana', 'cherry')
# nchar() counts characters in each string
result <- map(fruits, nchar)
print(result) # Returns a list
print(class(result))map_dbl() — 返回数值向量
map_dbl(.x, .f) 会将 .f 映射到 .x,并返回数值型(双精度)向量。如果任何结果不是单个数值,就会抛出错误;这种类型安全机制可以及早发现错误。
library(purrr)
groups <- list(
A = c(10, 20, 30),
B = c(5, 15, 25, 35),
C = c(100, 200)
)
# Compute mean for each group — returns a named numeric vector
means <- map_dbl(groups, mean)
print(means)
print(class(means))map_chr() — 返回字符向量
map_chr(.x, .f) 会执行映射并返回字符向量。它适合提取字符串属性、格式化结果或构建文件路径。该函数必须为每个元素返回一个字符串。
library(purrr)
models <- list(
m1 = lm(mpg ~ wt, data=mtcars),
m2 = lm(mpg ~ hp, data=mtcars),
m3 = lm(mpg ~ cyl, data=mtcars)
)
# Extract the formula from each model as a string
map_chr(models, function(m) deparse(formula(m)))map_lgl() — 返回逻辑向量
map_lgl(.x, .f) 返回由 TRUE/FALSE 值组成的逻辑向量。它非常适合对列表中的元素逐一测试条件,例如检查哪些元素满足某项标准。
library(purrr)
datasets <- list(
df1 = data.frame(x=1:3, y=c(NA,2,3)),
df2 = data.frame(x=1:3, y=4:6),
df3 = data.frame(x=c(NA,NA,3), y=1:3)
)
# Does each data frame contain any NA values?
map_lgl(datasets, function(df) anyNA(df))map_int() — 返回整数向量
map_int(.x, .f) 返回整数向量。当函数返回计数、索引或其他整数结果时,请使用它。注意:在 R 中,length() 和 nrow() 返回整数。
library(purrr)
my_lists <- list(
a = 1:10,
b = letters[1:5],
c = c(TRUE, FALSE, TRUE, TRUE)
)
# Count elements in each list item
map_int(my_lists, length)map_df() / map_dfr() — 返回数据框
map_df(.x, .f)(别名:map_dfr())会应用 .f,并将结果按行绑定为一个数据框。该函数必须为每个元素返回一个数据框或 tibble。map_dfc() 则按列绑定。
library(purrr)
files <- c('sales_q1', 'sales_q2', 'sales_q3')
# Simulate reading and labeling each file
map_df(files, function(f) {
data.frame(
file = f,
rows = sample(50:100, 1),
cols = 5
)
})使用 ~ 创建匿名函数
purrr 支持一种简洁的匿名函数公式写法:~expr,其中 .x 表示当前元素。这样无需编写 function(x) expr,即可让代码更加简洁。这两种写法的效果完全相同。
library(purrr)
numbers <- list(1, 4, 9, 16, 25)
# Three equivalent ways:
result1 <- map(numbers, function(x) x^2)
result2 <- map(numbers, ~.x^2)
result3 <- map_dbl(numbers, ~.x^2)
print(result2)
print(result3)遍历带名称的列表
当 .x 是带名称的列表或向量时,map() 的输出会保留这些名称。map_dbl() 及其他类型变体也会传递名称,使结果更易于理解。
library(purrr)
region_data <- list(
East = c(100, 120, 115, 130),
West = c(200, 195, 210, 205),
North = c(80, 85, 90, 88)
)
# Named results
map_dbl(region_data, mean)将 map() 与数据框列结合使用
数据框本质上是一个列的列表。map(df, fn) 会对每一列应用 fn。结合 map_dbl() 使用时,可以用简洁的方式一次性计算每一列的统计量。
library(purrr)
df <- data.frame(
score_a = c(85, 90, 78, 92),
score_b = c(88, 85, 80, 95),
score_c = c(92, 88, 84, 90)
)
# Mean of every column
map_dbl(df, mean)嵌套调用 map()
您可以嵌套调用 map() 来执行多层迭代:外层 map 遍历组,内层 map 遍历参数。这样可以用清晰且易于组合的结构替代嵌套的 for 循环。为保证可读性,请将嵌套深度控制在 2 层以内。
library(purrr)
groups <- list(A = 1:5, B = 6:10)
functions <- list(mean=mean, sd=sd, min=min)
# Apply each function to each group
map(groups, function(g) {
map_dbl(functions, function(f) f(g))
})快速检查
map() 和 map_dbl() 的主要区别是什么?
回顾:map() 与类型变体
关于 map() 和类型变体的要点:
map(.x, .f)— 始终返回列表;灵活性最高map_dbl()— 返回 numeric 向量;类型错误时会报错map_chr()— 返回字符向量map_lgl()— 返回逻辑向量map_int()— 返回整数向量map_df()/map_dfr()— 将结果按行绑定为数据框~.x简写 — 简洁的匿名函数语法- 带名称的输入会自动生成带名称的输出
library(purrr)
# Typed map showcase
data_list <- list(
group_A = c(10, 20, 30),
group_B = c(5, 15),
group_C = c(100, 200, 300, 400)
)
cat('Counts:', map_int(data_list, length), '\n')
cat('Means: ', map_dbl(data_list, mean), '\n')
cat('Any>50:', map_lgl(data_list, ~any(.x > 50)), '\n')常见问题解答
「map() 与类型化变体」课时是免费的吗?
是的 — 「map() 与类型化变体」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。
「map() 与类型化变体」这节课中我会学到什么?
使用 map()、map_dbl()、map_chr() 和 map_lgl() 对列表应用函数 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 R Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「map() 与类型化变体」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 R Academy 课中编写并运行代码吗?
能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。