选择 Choice
if...else if...else...
if (condition1) {
...
} else if (condition2) {
...
} else {
...
}
注意:
- 其中条件的长度应为1,长度大于1时报错!对于长度大于 1
的逻辑向量,要用
any(bool_vector)
和all(bool_vector)
获得一个长度为
1 的 Boolean 向量(一个 bool
值),再配合if(){}
和else if(){}
使用。
- 虽然
NA
是长度为 1 的 logical 向量,但
if(NA)
也会报错,要注意防止这一点。
- 可以充分利用
any()
和all()
的 na.rm
参数,令其为 TRUE
- 也可以使用
if(isTRUE(condition))
,isTRUE()
会在内部调用
identical(TRUE,x)
,只有 x 是长度为1的 TRUE,才能返回
TRUE
向量化形式:ifelse()
三元选择函数ifelse(condition, statement1, statement2)
中的三个参数可以是任意长度的向量,按各自分量执行向量化操作
R
中这个函数是向量化的,使用起来要慎之又慎!!!比如条件只有一个分量,则
statement1 和 statement2 就只有一个分量参与运算。
switch(statement, list)
list 是一组键值对,statement 是一个键,返回 list
中与该键对应的值。
switch(x,
a = "option 1",
b = "option 2",
c = "option 3",
stop("Invalid `x` value")
)
result1 <- switch("fruit",
meat = "chicken",
fruit = "apple",
vegetable = "cucumber",
"soup"
)
result1
#> [1] "apple"
result2 <- switch("final",
meat = "chicken",
fruit = "apple",
vegetable = "cucumber",
"soup"
)
result2 # 都不匹配时,返回无key的值
#> [1] "soup"
简化形式
switch(k, para1, para2, ..., paran)
,根据整数 k 返回第 k
个参数值。k 在 1:n 的范围之外时,返回 NULL
循环 Loop
能不用显式循环就不用,多用高阶函数实现迭代!
repeat {}
必须手动指定 break 条件,否则无限循环。这在创建交互式 app
时很有用。
while (condition) {}
只要 condition 取值为 TRUE,就继续循环;取值为 FALSE 时,离开循环
实践中, while
循环通常使用在迭代次数未知的情况下。例如从数据库的查询中分块地获取结果,相应的代码可能如下所示
res <- dbSendQuery(con, "SELECT * FROM table1 WHERE type = 1")
while (!dbHasCompleted(res)) {
chunk <- dbFetch(res, 10000)
process(chunk)
}
# 一小块一小块地处理查询结果,避免将一个(也许是巨大的)数据框读取到内存中
# 这样,仅需占用很小的内存空间就可以处理大量的数据
# 不过,前提条件是 process( ) 算法必须支持这种数据处理方式
for(iterator in sequence) {}
提高循环速度:预先分配空间
R 中如果对对象的 size
做了改动(如添加一个元素),要把整个数据结构都重新拷贝一份,这非常慢。如果在每次循环中都有这种语句,时间复杂度会是\(\mathrm{O}\left(\mathrm{n}^{2}\right)\)级的。
所以最好在开始循环前,预先声明一个空向量/列表(out <- vector("list", length(x))
),为输出结果分配足够的空间,避免频繁拷贝。循环结束后,可能需要打散并重组为我们需要的对象:对于向量用unlist()
,数据框用dplyr::bind_rows()
参考 JS 语法:
const arr = [];
for (let i = 0; i < 6; i++) {
arr.push(i ^ 2 % 11);
}
console.log(arr);
例:
df <- tibble(
a = rnorm(10),
b = rnorm(10),
c = rnorm(10),
d = rnorm(10)
)
# 求df各列的中位数,先为输出分配空间,长度为ncol(df)的向量
output <- numeric(ncol(df))
for (i in 1:ncol(df)) {
output[[i]] <- median(df[[i]])
}
output
#> [1] -0.38994378 0.24621722 -0.01565543 0.06217146
循环取元素通常会剥离属性
xs <- as.Date(c("2020-01-01", "2010-01-01"))
for (x in xs) { # 直接取元素,剥离 class 属性
str_c(x, x %>% class(), sep = ', ') %>% print()
}
#> [1] "18262, numeric"
#> [1] "14610, numeric"
for (i in seq_along(xs)) {
str_c(xs[[i]], xs[[i]] %>% class(), sep = ', ') %>% print()
}
#> [1] "2020-01-01, Date"
#> [1] "2010-01-01, Date"
# 还是 purrr 包的高阶函数安全
xs %>% walk(function(x){
str_c(x, x %>% class(), sep = ', ') %>% print()
})
#> [1] "2020-01-01, Date"
#> [1] "2010-01-01, Date"
条件系统 Condition
LS0tDQp0aXRsZTogIkNvbnRyb2wgRmxvd3MiDQpzdWJ0aXRsZTogIiINCmF1dGhvcjogIkh1bW9vbiINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDogaHRtbF9kb2N1bWVudA0KZG9jdW1lbnRjbGFzczogY3RleGFydA0KY2xhc3NvcHRpb246IGh5cGVycmVmLA0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQpzb3VyY2UoIi4uL1JtYXJrZG93bi10ZW1wbGF0ZS9SbWFya2Rvd25fY29uZmlnLlIiKQ0KDQojIyBnbG9iYWwgb3B0aW9ucyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICB3aWR0aCA9IGNvbmZpZyR3aWR0aCwNCiAgZmlnLndpZHRoID0gY29uZmlnJGZpZy53aWR0aCwNCiAgZmlnLmFzcCA9IGNvbmZpZyRmaWcuYXNwLA0KICBvdXQud2lkdGggPSBjb25maWckb3V0LndpZHRoLA0KICBmaWcuYWxpZ24gPSBjb25maWckZmlnLmFsaWduLA0KICBmaWcucGF0aCA9IGNvbmZpZyRmaWcucGF0aCwNCiAgZmlnLnNob3cgPSBjb25maWckZmlnLnNob3csDQogIHdhcm4gPSBjb25maWckd2FybiwNCiAgd2FybmluZyA9IGNvbmZpZyR3YXJuaW5nLA0KICBtZXNzYWdlID0gY29uZmlnJG1lc3NhZ2UsDQogIGVjaG8gPSBjb25maWckZWNobywNCiAgZXZhbCA9IGNvbmZpZyRldmFsLA0KICB0aWR5ID0gY29uZmlnJHRpZHksDQogIGNvbW1lbnQgPSBjb25maWckY29tbWVudCwNCiAgY29sbGFwc2UgPSBjb25maWckY29sbGFwc2UsDQogIGNhY2hlID0gY29uZmlnJGNhY2hlLA0KICBjYWNoZS5jb21tZW50cyA9IGNvbmZpZyRjYWNoZS5jb21tZW50cywNCiAgYXV0b2RlcCA9IGNvbmZpZyRhdXRvZGVwDQopDQpgYGANCg0KIyMg6YCJ5oupIENob2ljZQ0KDQojIyMgYGlmLi4uZWxzZSBpZi4uLmVsc2UuLi5gDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KaWYgKGNvbmRpdGlvbjEpIHsNCiAgLi4uDQp9IGVsc2UgaWYgKGNvbmRpdGlvbjIpIHsNCiAgLi4uDQp9IGVsc2Ugew0KICAuLi4NCn0NCmBgYA0KDQrms6jmhI/vvJoNCg0KMS4gIOWFtuS4readoeS7tueahOmVv+W6puW6lOS4ujHvvIzplb/luqblpKfkuo4x5pe25oql6ZSZ77yB5a+55LqO6ZW/5bqm5aSn5LqOIDEg55qE6YC76L6R5ZCR6YeP77yM6KaB55SoYGFueShib29sX3ZlY3Rvcilg5ZKMYGFsbChib29sX3ZlY3Rvcilg6I635b6X5LiA5Liq6ZW/5bqm5Li6IDEg55qEIEJvb2xlYW4g5ZCR6YeP77yI5LiA5LiqIGJvb2wg5YC877yJ77yM5YaN6YWN5ZCIYGlmKCl7fWDlkoxgZWxzZSBpZigpe31g5L2/55So44CCDQoyLiAg6Jm954S2IGBOQWAg5piv6ZW/5bqm5Li6IDEg55qEIGxvZ2ljYWwg5ZCR6YeP77yM5L2GIGBpZihOQSlgIOS5n+S8muaKpemUme+8jOimgeazqOaEj+mYsuatoui/meS4gOeCueOAgg0KICAgIDEuICDlj6/ku6XlhYXliIbliKnnlKhgYW55KClg5ZKMYGFsbCgpYOeahCBuYS5ybSDlj4LmlbDvvIzku6TlhbbkuLogVFJVRQ0KICAgIDIuICDkuZ/lj6/ku6Xkvb/nlKggYGlmKGlzVFJVRShjb25kaXRpb24pKWDvvIxgaXNUUlVFKClg5Lya5Zyo5YaF6YOo6LCD55SoIGBpZGVudGljYWwoVFJVRSx4KWDvvIzlj6rmnIkgeCDmmK/plb/luqbkuLox55qEIFRSVUXvvIzmiY3og73ov5Tlm54gVFJVRQ0KDQojIyMg5ZCR6YeP5YyW5b2i5byP77yaYGlmZWxzZSgpYA0KDQrkuInlhYPpgInmi6nlh73mlbBgaWZlbHNlKGNvbmRpdGlvbiwgc3RhdGVtZW50MSwgc3RhdGVtZW50Milg5Lit55qE5LiJ5Liq5Y+C5pWw5Y+v5Lul5piv5Lu75oSP6ZW/5bqm55qE5ZCR6YeP77yM5oyJ5ZCE6Ieq5YiG6YeP5omn6KGM5ZCR6YeP5YyW5pON5L2cDQoNCj4gUiDkuK3ov5nkuKrlh73mlbDmmK/lkJHph4/ljJbnmoTvvIzkvb/nlKjotbfmnaXopoHmhY7kuYvlj4jmhY7vvIHvvIHvvIHmr5TlpoLmnaHku7blj6rmnInkuIDkuKrliIbph4/vvIzliJkgc3RhdGVtZW50MSDlkowgc3RhdGVtZW50MiDlsLHlj6rmnInkuIDkuKrliIbph4/lj4LkuI7ov5DnrpfjgIINCg0KIyMjIGBzd2l0Y2goc3RhdGVtZW50LCBsaXN0KWANCg0KbGlzdCDmmK/kuIDnu4TplK7lgLzlr7nvvIxzdGF0ZW1lbnQg5piv5LiA5Liq6ZSu77yM6L+U5ZueIGxpc3Qg5Lit5LiO6K+l6ZSu5a+55bqU55qE5YC844CCDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0Kc3dpdGNoKHgsDQogIGEgPSAib3B0aW9uIDEiLA0KICBiID0gIm9wdGlvbiAyIiwNCiAgYyA9ICJvcHRpb24gMyIsDQogIHN0b3AoIkludmFsaWQgYHhgIHZhbHVlIikNCikNCmBgYA0KDQpgYGB7cn0NCnJlc3VsdDEgPC0gc3dpdGNoKCJmcnVpdCIsDQogIG1lYXQgPSAiY2hpY2tlbiIsDQogIGZydWl0ID0gImFwcGxlIiwNCiAgdmVnZXRhYmxlID0gImN1Y3VtYmVyIiwNCiAgInNvdXAiDQopDQpyZXN1bHQxDQoNCg0KcmVzdWx0MiA8LSBzd2l0Y2goImZpbmFsIiwNCiAgbWVhdCA9ICJjaGlja2VuIiwNCiAgZnJ1aXQgPSAiYXBwbGUiLA0KICB2ZWdldGFibGUgPSAiY3VjdW1iZXIiLA0KICAic291cCINCikNCnJlc3VsdDIgIyDpg73kuI3ljLnphY3ml7bvvIzov5Tlm57ml6BrZXnnmoTlgLwNCmBgYA0KDQojIyMjIOeugOWMluW9ouW8jw0KDQpgc3dpdGNoKGssIHBhcmExLCBwYXJhMiwgLi4uLCBwYXJhbilg77yM5qC55o2u5pW05pWwIGsg6L+U5Zue56ysIGsg5Liq5Y+C5pWw5YC844CCayDlnKggMTpuIOeahOiMg+WbtOS5i+WkluaXtu+8jOi/lOWbniBOVUxMDQoNCiMjIOW+queOryBMb29wDQoNCioq6IO95LiN55So5pi+5byP5b6q546v5bCx5LiN55So77yM5aSa55So6auY6Zi25Ye95pWw5a6e546w6L+t5Luj77yBKioNCg0KIyMjIGByZXBlYXQge31gDQoNCuW/hemhu+aJi+WKqOaMh+WumiBicmVhayDmnaHku7bvvIzlkKbliJnml6DpmZDlvqrnjq/jgILov5nlnKjliJvlu7rkuqTkupLlvI8gYXBwIOaXtuW+iOacieeUqOOAgg0KDQojIyMgYHdoaWxlIChjb25kaXRpb24pIHt9YA0KDQrlj6ropoEgY29uZGl0aW9uIOWPluWAvOS4uiBUUlVF77yM5bCx57un57ut5b6q546v77yb5Y+W5YC85Li6IEZBTFNFIOaXtu+8jOemu+W8gOW+queOrw0KDQrlrp7ot7XkuK3vvIwgd2hpbGUg5b6q546v6YCa5bi45L2/55So5Zyo6L+t5Luj5qyh5pWw5pyq55+l55qE5oOF5Ya15LiL44CC5L6L5aaC5LuO5pWw5o2u5bqT55qE5p+l6K+i5Lit5YiG5Z2X5Zyw6I635Y+W57uT5p6c77yM55u45bqU55qE5Luj56CB5Y+v6IO95aaC5LiL5omA56S6DQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KcmVzIDwtIGRiU2VuZFF1ZXJ5KGNvbiwgIlNFTEVDVCAqIEZST00gdGFibGUxIFdIRVJFIHR5cGUgPSAxIikNCndoaWxlICghZGJIYXNDb21wbGV0ZWQocmVzKSkgew0KICBjaHVuayA8LSBkYkZldGNoKHJlcywgMTAwMDApDQogIHByb2Nlc3MoY2h1bmspDQp9DQojIOS4gOWwj+Wdl+S4gOWwj+Wdl+WcsOWkhOeQhuafpeivoue7k+aenO+8jOmBv+WFjeWwhuS4gOS4qu+8iOS5n+iuuOaYr+W3qOWkp+eahO+8ieaVsOaNruahhuivu+WPluWIsOWGheWtmOS4rQ0KIyDov5nmoLfvvIzku4XpnIDljaDnlKjlvojlsI/nmoTlhoXlrZjnqbrpl7TlsLHlj6/ku6XlpITnkIblpKfph4/nmoTmlbDmja4NCiMg5LiN6L+H77yM5YmN5o+Q5p2h5Lu25pivIHByb2Nlc3MoICkg566X5rOV5b+F6aG75pSv5oyB6L+Z56eN5pWw5o2u5aSE55CG5pa55byPDQpgYGANCg0KIyMjIGBmb3IoaXRlcmF0b3IgaW4gc2VxdWVuY2UpIHt9YA0KDQojIyMgYGJyZWFrYCDlhbPplK7lrZcNCg0K56a75byA5b6q546vDQoNCiMjIyBgbmV4dGAg5YWz6ZSu5a2XDQoNCuemu+W8gOacrOi9ruW+queOr++8jOS7juS4i+S4gOi9ruW+queOr+W8gOWniw0KDQojIyMg5o+Q6auY5b6q546v6YCf5bqm77ya6aKE5YWI5YiG6YWN56m66Ze0DQoNClIg5Lit5aaC5p6c5a+55a+56LGh55qEIHNpemUg5YGa5LqG5pS55Yqo77yI5aaC5re75Yqg5LiA5Liq5YWD57Sg77yJ77yM6KaB5oqK5pW05Liq5pWw5o2u57uT5p6E6YO96YeN5paw5ou36LSd5LiA5Lu977yM6L+Z6Z2e5bi45oWi44CC5aaC5p6c5Zyo5q+P5qyh5b6q546v5Lit6YO95pyJ6L+Z56eN6K+t5Y+l77yM5pe26Ze05aSN5p2C5bqm5Lya5pivJFxtYXRocm17T31cbGVmdChcbWF0aHJte259XnsyfVxyaWdodCkk57qn55qE44CCDQoNCuaJgOS7peacgOWlveWcqOW8gOWni+W+queOr+WJje+8jOmihOWFiOWjsOaYjuS4gOS4quepuuWQkemHjy/liJfooajvvIhgb3V0IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCh4KSlg77yJ77yM5Li66L6T5Ye657uT5p6c5YiG6YWN6Laz5aSf55qE56m66Ze077yM6YG/5YWN6aKR57mB5ou36LSd44CC5b6q546v57uT5p2f5ZCO77yM5Y+v6IO96ZyA6KaB5omT5pWj5bm26YeN57uE5Li65oiR5Lus6ZyA6KaB55qE5a+56LGh77ya5a+55LqO5ZCR6YeP55SoYHVubGlzdCgpYO+8jOaVsOaNruahhueUqGBkcGx5cjo6YmluZF9yb3dzKClgDQoNCuWPguiAgyBKUyDor63ms5U6DQoNCmBgYHtqc30NCmNvbnN0IGFyciA9IFtdOw0KZm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpKyspIHsNCiAgYXJyLnB1c2goaSBeIDIgJSAxMSk7DQp9DQpjb25zb2xlLmxvZyhhcnIpOw0KYGBgDQoNCuS+i++8mg0KDQpgYGB7cn0NCmRmIDwtIHRpYmJsZSgNCiAgYSA9IHJub3JtKDEwKSwNCiAgYiA9IHJub3JtKDEwKSwNCiAgYyA9IHJub3JtKDEwKSwNCiAgZCA9IHJub3JtKDEwKQ0KKQ0KDQojIOaxgmRm5ZCE5YiX55qE5Lit5L2N5pWw77yM5YWI5Li66L6T5Ye65YiG6YWN56m66Ze077yM6ZW/5bqm5Li6bmNvbChkZinnmoTlkJHph48NCm91dHB1dCA8LSBudW1lcmljKG5jb2woZGYpKQ0KZm9yIChpIGluIDE6bmNvbChkZikpIHsNCiAgb3V0cHV0W1tpXV0gPC0gbWVkaWFuKGRmW1tpXV0pDQp9DQpvdXRwdXQNCmBgYA0KDQojIyMg5b6q546v5Y+W5YWD57Sg6YCa5bi45Lya5Yml56a75bGe5oCnDQoNCmBgYHtyfQ0KeHMgPC0gYXMuRGF0ZShjKCIyMDIwLTAxLTAxIiwgIjIwMTAtMDEtMDEiKSkNCg0KZm9yICh4IGluIHhzKSB7ICMg55u05o6l5Y+W5YWD57Sg77yM5Yml56a7IGNsYXNzIOWxnuaApw0KICBzdHJfYyh4LCB4ICU+JSBjbGFzcygpLCBzZXAgPSAnLCAnKSAlPiUgcHJpbnQoKQ0KfQ0KDQpmb3IgKGkgaW4gc2VxX2Fsb25nKHhzKSkgew0KICBzdHJfYyh4c1tbaV1dLCB4c1tbaV1dICU+JSBjbGFzcygpLCBzZXAgPSAnLCAnKSAlPiUgcHJpbnQoKQ0KfQ0KDQojIOi/mOaYryBwdXJyciDljIXnmoTpq5jpmLblh73mlbDlronlhagNCnhzICU+JSB3YWxrKGZ1bmN0aW9uKHgpew0KICBzdHJfYyh4LCB4ICU+JSBjbGFzcygpLCBzZXAgPSAnLCAnKSAlPiUgcHJpbnQoKQ0KfSkNCmBgYA0KDQojIyDmnaHku7bns7vnu58gQ29uZGl0aW9uDQo=