为何我的R函数无需for循环即可遍历dataframe行?
问题背景
我有如下结构的DataFrame:
| ImportantNumber | ImportantWord | LookupVar1 | LookupVar2 | LookupVar3 |
|---|---|---|---|---|
| 100 | Mxyztplk | 2 | 3 | NA |
| 200 | Murgatroyd | NA | 3 | 2 |
| 300 | Veeblefetzer | 3 | NA | NA |
同时编写了如下函数:
my_function <- function(LookupVar){ ImportantNumber <-(df$ImportantNumber[!is.na(df[[LookupVar]])]) ImportantWord <- (df$ImportantWord[!is.na(df[[LookupVar]])]) cat(paste(ImportantNumber, ImportantWord, collapse = "\n")) }
该函数运行效果符合预期,例如调用my_function("LookupVar1")会输出:
#> 100 Mxyztplk #> 300 Veeblefetzer
调用my_function("LookupVar2")会输出:
#> 100 Mxyztplk #> 200 Murgatroyd
可见该函数会遍历LookupVarN所指向列的每一行,想请教:为何无需指定for循环或其他流程控制语句,该函数就能实现这样的遍历?
解答
这是因为R是向量化编程语言,大部分操作默认会对整个向量(比如DataFrame的列)进行批量处理,无需手动编写循环。
具体到你的函数里,核心逻辑的每一步都是向量化操作:
!is.na(df[[LookupVar]]):df[[LookupVar]]取出指定列(本质是一个向量),is.na()会自动遍历这个向量的每一个元素,判断是否为NA,返回一个和原向量长度一致的布尔向量(TRUE/FALSE)。前面加!是反转结果,得到“非NA元素所在位置为TRUE”的向量。df$ImportantNumber[布尔向量]:R的向量索引支持用布尔向量筛选元素——它会自动提取所有对应位置为TRUE的元素,相当于一次性完成了“遍历每一行、判断是否保留”的操作,不用写循环。paste(ImportantNumber, ImportantWord, collapse = "\n"):paste也是向量化的,它会把两个向量里对应位置的元素配对拼接,再用换行符把所有结果连起来,同样是批量处理。
简单来说,R已经把循环的细节封装在底层了,你写的单条语句背后,已经完成了对整个列的遍历和筛选。
内容的提问来源于stack exchange,提问作者Luis Morales Knight
相关产品推荐
相关产品推荐

