尝试在R中编写分段函数
我对R相当陌生,想写一个分段函数,我的代码不起作用,如果你能帮忙,请评论:尝试在R中编写分段函数,r,R,我对R相当陌生,想写一个分段函数,我的代码不起作用,如果你能帮忙,请评论: a<-rnorm(1000) ifelse(0<a & a<=.3,C=sqrt(30*a),NA) ifelse(.3<a & a<=.7,C=5*a+15/10),NA) ifelse(.7<a & a<=1,c=8-sqrt(-30*a+30),NA) a三个问题: 当直接用作函数调用参数列表的一部分时,=不是赋值运算符,
a<-rnorm(1000)
ifelse(0<a & a<=.3,C=sqrt(30*a),NA)
ifelse(.3<a & a<=.7,C=5*a+15/10),NA)
ifelse(.7<a & a<=1,c=8-sqrt(-30*a+30),NA)
a三个问题:
当直接用作函数调用参数列表的一部分时,=
不是赋值运算符,而是命名参数的语法
与其尝试在ifelse()
函数调用参数列表中赋值,不如赋值结果
您当前正在执行三个不同的计算。真的,你只想表演一个。要解决此问题,您需要嵌套您的呼叫:
这两种解决方案都有一个不幸的副作用,即由于NaN值(由计算负数平方根的代码引起)而引发警告。有关解决此问题的方法,请参阅。三个问题:
当直接用作函数调用参数列表的一部分时,=
不是赋值运算符,而是命名参数的语法
与其尝试在ifelse()
函数调用参数列表中赋值,不如赋值结果
您当前正在执行三个不同的计算。真的,你只想表演一个。要解决此问题,您需要嵌套您的呼叫:
这两种解决方案都有一个不幸的副作用,即由于NaN值(由计算负数平方根的代码引起)而引发警告。有关解决此问题的方法,请参阅。在10之后的第二个ifelse
语句中有一个额外的括号。您可以删除它或添加另一对。在10之后的第二个ifelse
语句中有一个额外的括号。您可以删除它或添加另一对。关于问题中的代码:
作业应该在ifelse外部完成,而不是在内部完成
ifelse将首先计算所有值的两个支腿,因此如果传递负数a
,它将尝试获取负数的平方根,即使未选择该支腿。因此,最好避免在此处完全使用ifelse
嵌套的ifelse可能很难遵循
下面的解决方案避免了ifelse
。第一个使用if。。。其他的与ifelse
不同,它只计算实际使用的支腿。它只适用于标量,但我们可以使用Vectorize
将我们编写的标量函数转换为接受向量的函数
第二种解决方案将介于0和1之间的a
的值与其他值分开,这样我们就不会尝试取负数的平方根,因此主计算中不涉及NA。它使用成语cond1*y1+cond2*y2+。。。其中y1,y2。。。是数值非NA表达式和cond1、cond2、。。。是相互排斥的条件。对于每个向量分量,只有一个条件为真,因此R将相应的表达式乘以1,保持不变,其他条件乘以0,消除它们
1)使用if/else并将其矢量化。这即使适用于a的负值,也不会发出警告,否则可能会由于负平方根而发出警告,并且不会使用包
f <- Vectorize(function(a)
if (0 < a & a <= 0.3) sqrt(30 * a)
else if (0.3 < a & a <= 0.7) 5 * a + 15 / 10
else if (0.7 < a & a <= 1) 8 - sqrt(-30 * a + 30)
else NA)
a <- seq(0, 1, 0.01)
c <- f(a)
head(c)
## [1] NA 0.5477226 0.7745967 0.9486833 1.0954451 1.2247449
tail(c)
## [1] 6.775255 6.904555 7.051317 7.225403 7.452277 8.000000
plot(c ~ a, type = "l")
f关于问题中的代码:
作业应该在ifelse外部完成,而不是在内部完成
ifelse将首先计算所有值的两个支腿,因此如果传递负数a
,它将尝试获取负数的平方根,即使未选择该支腿。因此,最好避免在此处完全使用ifelse
嵌套的ifelse可能很难遵循
下面的解决方案避免了ifelse
。第一个使用if。。。其他的与ifelse
不同,它只计算实际使用的支腿。它只适用于标量,但我们可以使用Vectorize
将我们编写的标量函数转换为接受向量的函数
第二种解决方案将介于0和1之间的a
的值与其他值分开,这样我们就不会尝试取负数的平方根,因此主计算中不涉及NA。它使用成语cond1*y1+cond2*y2+。。。其中y1,y2。。。是数值非NA表达式和cond1、cond2、。。。是相互排斥的条件。对于每个向量分量,只有一个条件为真,因此R将相应的表达式乘以1,保持不变,其他条件乘以0,消除它们
1)使用if/else并将其矢量化。这即使适用于a的负值,也不会发出警告,否则可能会由于负平方根而发出警告,并且不会使用包
f <- Vectorize(function(a)
if (0 < a & a <= 0.3) sqrt(30 * a)
else if (0.3 < a & a <= 0.7) 5 * a + 15 / 10
else if (0.7 < a & a <= 1) 8 - sqrt(-30 * a + 30)
else NA)
a <- seq(0, 1, 0.01)
c <- f(a)
head(c)
## [1] NA 0.5477226 0.7745967 0.9486833 1.0954451 1.2247449
tail(c)
## [1] 6.775255 6.904555 7.051317 7.225403 7.452277 8.000000
plot(c ~ a, type = "l")
f谢谢,它成功了!!非常感谢我希望base R有这样的案例陈述。。。我发现嵌套的ifelse
更难可视化(因此也更难维护),更不用说ifelse
不安全的责任了。从长远来看,我发现dplyr::case_when
和data.table::fcase
要好得多,不过我还是希望它能在base R的某个地方找到…@r2evans是的,base R奇怪地缺少一个有用的开关
表达式(实际的switch()
函数非常糟糕)。谢谢你,它成功了!!非常感谢我希望base R有这样的案例陈述。。。我发现嵌套的ifelse
更难可视化(因此也更难维护),更不用说ifelse
不安全的责任了。从长远来看,我发现dplyr::case_when
和data.table::fcase
要好得多,尽管我还是希望它能在base R的某个地方找到…@r2evans是的,base R奇怪地缺少一个有用的switch
表达式(实际的switch()
函数是
f <- Vectorize(function(a)
if (0 < a & a <= 0.3) sqrt(30 * a)
else if (0.3 < a & a <= 0.7) 5 * a + 15 / 10
else if (0.7 < a & a <= 1) 8 - sqrt(-30 * a + 30)
else NA)
a <- seq(0, 1, 0.01)
c <- f(a)
head(c)
## [1] NA 0.5477226 0.7745967 0.9486833 1.0954451 1.2247449
tail(c)
## [1] 6.775255 6.904555 7.051317 7.225403 7.452277 8.000000
plot(c ~ a, type = "l")
f2 <- function(x) {
ix <- x > 0 & x <= 1
a <- x[ix]
replace(NA * x, ix, (0 < a & a <= 0.3) * sqrt(30 * a) +
(0.3 < a & a <= 0.7) * (5 * a + 15 / 10) +
(0.7 < a & a <= 1) * (8 - sqrt(-30 * a + 30)))
}
# test
c2 <- f(a)
identical(c, c2)
## [1] TRUE