r - 错误条件超过 1 个函数 if else [编辑:rowwise]
问题描述
TL;DR:我的函数不是向量化的吗?如何使用许多 if & else 语句对调用其他函数的函数进行矢量化?非常感谢!
编辑:该功能在控制台中一次手动执行一棵树时起作用,或者在使用时使用 dplyr-styledplyr::rowwise
我正在编写一个包含很多 if 和 'else' 的函数。
该函数根据提供(或缺少)哪些参数来决定使用哪个函数来计算树的体积。
我想像这样使用它,dplyr 风格,在一个包含许多案例的巨大数据表上。
tree_data %>% mutate(volume = tree.volume(dbh.cm = dbh.cm, height.m= height, species.latin=species.latin, latitude= latitude)
缺少crown.base.height.m 和double.bark.mm 是很常见的(有没有这些参数的体积函数)。
tree.volume <- function(dbh.cm,height.m,crown.base.height.m,double.bark.mm,species.latin,latitude){
if(grepl("^Pinus", ignore.case=TRUE, species.latin)){
pinus_spp_vol(species.latin = species.latin,
dbh.cm = dbh.cm,
height.m = height.m,
latitude = latitude,
double.bark.mm = double.bark.mm,
crown.base.height.m = crown.base.height.m)
} else if(grepl("^Picea|^Abies",ignore.case = TRUE, species.latin)){
picea_spp_vol(dbh.cm = dbh.cm,
height.m = height.m,
latitude = latitude,
crown.base.height.m = crown.base.height.m)
} else if(grepl("^Larix", ignore.case = TRUE, species.latin)){
larix_sibirica_vol_carbonnier_1954(dbh.cm = dbh.cm,
height.m = height.m,
double.bark.mm = double.bark.mm,
crown.base.height.m = crown.base.height.m)
}
}
我收到警告消息:
1: 在 if (grepl("^Pinus", ignore.case = TRUE, species.latin)) { :
条件长度 > 1 并且只使用第一个元素
2: 在 if (species.latin == "Pinus contorta") { : 条件长度 > 1 并且只使用第一个元素
3: 在 if (dbh.cm >= 4.5) { : 条件长度 > 1 并且只使用第一个元素
4: 在 if (latitude >= 60) { : 条件长度 > 1 并且只使用第一个元素
我把它读成函数一次不处理我的data.frame中的一行......因此认为我的所有行都与第一行处于相同的“类别”下?
附:读取导致错误的 if 语句的第一个函数:
pinus_spp_vol <- function(species.latin, dbh.cm, height.m, crown.base.height.m, double.bark.mm, latitude){
if(!missing(crown.base.height.m)){
if(!missing(double.bark.mm)){
if(species.latin!="Pinus contorta"){
if(dbh.cm >= 4.5){ #Brandel, 1990 function 100-4. for Pines above 4.5 cm dbh.
if(latitude >= 60){
(10^-1.12715)*(dbh.cm^2.13211)*((dbh.cm+20)^-0.13543)*(height.m^1.58121)*((height.m-1.3)^-0.73435)*(crown.base.height.m^0.06595)*(double.bark.mm^-0.10998)
} else {
(10^-1.20042)*(dbh.cm^2.10263)*((dbh.cm+20)^-0.07366)*(height.m^1.99751)*((height.m-1.3)^-1.11357)*(crown.base.height.m^0.06420)*(double.bark.mm^-0.14963)
}
} else { #Andersson,1954 for small trees.
if(latitude >= 60){
0.22 + 0.08786 * (dbh.cm^2) + 0.03045 * (dbh.cm^2) * height.m + 0.002809 * dbh.cm * (height.m^2)
} else {
0.22 + 0.1066 * (dbh.cm^2) + 0.02085 * (dbh.cm^2) * height.m + 0.008427 * dbh.cm * (height.m^2)
}
}
}
}
} else {
if(species.latin== "Pinus contorta"){ #Eriksson 1973
0.1121*(dbh.cm^2) + 0.02870*(dbh.cm^2)*height.m - 0.000061*(dbh.cm^2)*(height.m^2) - 0.09176*dbh.cm*height.m + 0.01249*dbh.cm*(height.m^2)
} else {
if(dbh.cm >= 4.5){#Brandel 1990, 100-01
if(latitude >= 60){
(10^-1.20914)*(dbh.cm^1.94740)*((dbh.cm+20)^-0.05947)*(height.m^1.40958)*((height.m-1.3)^-0.45810)
} else {
(10^-1.38903)*(dbh.cm^1.84493)*((dbh.cm+20)^0.06563)*(height.m^2.02122)*((height.m-1.3)^-1.01095)
}
} else { #Andersson,1954 for small trees.
if(latitude >= 60){
0.22 + 0.08786 * (dbh.cm^2) + 0.03045 * (dbh.cm^2) * height.m + 0.002809 * dbh.cm * (height.m^2)
} else {
0.22 + 0.1066 * (dbh.cm^2) + 0.02085 * (dbh.cm^2) * height.m + 0.008427 * dbh.cm * (height.m^2)
}
}
}
}
}
解决方案
您将 non-vectorizedif () ... else ...
与 vectorized混淆了ifelse
。
if () ... else ...
接受单个 (!!) 条件并对条件是否为TRUE
或执行操作FALSE
。如果您改为为条件传递(逻辑)向量,则仅选择向量的第一个元素来决定要执行的操作。作为通知,R 将发出警告。但是,除此之外,您通常会得到错误或非预期的结果。
ifelse
另一方面是矢量化的,即检查两个条件并按元素采取行动。对于所有TRUE
元素,TRUE
选择动作,对于所有FALSE
元素,FALSE
选择动作。
一个简单的例子可以很好地看出这一点:
power2 <- function(x) x^2
power3 <- function(x) x^3
myfun_warning <- function(cyl) {
if (cyl == 4) {
power2(cyl)
} else {
power3(cyl)
}
}
myfun_no_warning <- function(cyl) {
ifelse(cyl == 4, power2(cyl), power3(cyl))
}
# Warning and incorrect result
myfun_warning(mtcars$cyl)
#> Warning in if (cyl == 4) {: the condition has length > 1 and only the first
#> element will be used
#> [1] 216 216 64 216 512 216 512 64 64 216 216 512 512 512 512 512 512 64 64
#> [20] 64 64 512 512 512 512 64 64 64 512 216 512 64
# No warning and correct result
myfun_no_warning(mtcars$cyl)
#> [1] 216 216 16 216 512 216 512 16 16 216 216 512 512 512 512 512 512 16 16
#> [20] 16 16 512 512 512 512 16 16 16 512 216 512 16
推荐阅读
- python - 为 opencv python 包安装 gstreamer 支持
- typescript - 在类外声明变量
- servicestack - servicestack 和 Serilog 无法正常工作
- python - Python 3x:导入数学库 python
- angular - 如何将 Angular ngAfterViewInit 与 BehaviorSubject 一起使用并创建 Bing Map 实例
- javascript - js 中的 HTML 和 PHP
- matplotlib - 为什么将 seaborn 重绘的“种类”从“散布”更改为“线”会使时间序列出现错误?
- mysql - SQL中重复字符串的子字符串索引
- branch.io - 在 Web 集成中将 $mixpanel_distinct_id 传递给 Branch.io
- php - Moodle 课程 ID 始终等于 1