R 具有多个条件if、else或ifelse的函数
我在研究潜水行为,然后我有一个功能,在数据框中创建一个新的列,每个潜水的拨号相位(白天、黎明、夜晚和黄昏)由太阳角度决定,但很明显,它们的条件相互重叠。我的真实数据帧有超过90.000行 (1) 黎明是根据相对于地平线的-12到+6度的太阳高度来分类的,在日出时,(2)黄昏是根据日落时从+6到-12度的太阳高度来分类的。(3) 白天的温度高于+6度,夜晚的温度低于-12度R 具有多个条件if、else或ifelse的函数,r,function,if-statement,conditional-statements,R,Function,If Statement,Conditional Statements,我在研究潜水行为,然后我有一个功能,在数据框中创建一个新的列,每个潜水的拨号相位(白天、黎明、夜晚和黄昏)由太阳角度决定,但很明显,它们的条件相互重叠。我的真实数据帧有超过90.000行 (1) 黎明是根据相对于地平线的-12到+6度的太阳高度来分类的,在日出时,(2)黄昏是根据日落时从+6到-12度的太阳高度来分类的。(3) 白天的温度高于+6度,夜晚的温度低于-12度 dt = data.table(localtime= c("2016-10-24 12:45:06",
dt = data.table(localtime= c("2016-10-24 12:45:06", "2016-10-24 12:46:13", "2016-10-24 12:47:02", "2016-10-24 12:48:27", "2016-10-24 12:52:39", "2016-10-24 12:55:11", "2016-10-30 21:08:02", "2016-10-30 21:18:27", "2016-10-30 21:30:13","2016-10-24 23:27:21", "2016-10-26 06:54:29"),
lon = c(-39.94400, -39.94410, -39.94418, -39.94432, -39.94472, -39.94496, -40.87705, -40.87567, -40.87409, -40.00234, -40.59864),
DepthMean = 30, 50, 200, 76, 467, 87, 98, 10, 240, 176, 89))
我的猜测是因为使用if
、else
或ifelse
,函数会正常工作,对吗?我不具备使用这些代码执行do函数的能力。有人能帮忙吗
我试过这种方法,但缺少一个阶段
> f1<-function(df) {
+ #loading the necessary package
+ require(oce)
+
+ #getting the sun angle from local time, longitude and latitude by the correction for atmospheric refraction
+ x2<-sunAngle(df$localtime, df$lon, df$lon, useRefraction = TRUE)
+
+ #converting into data.frame
+ x3<-do.call(rbind, lapply(x2$altitude, as.data.frame))
+
+ #creating new colum with the sun angles
+ df$sun<- x3$`X[[i]]`
+
+ #creating new column with only by hour about local time to do the next conditions
+ df$hourBRT <- as.POSIXlt(df$localtime)$hour
+ df <- df[!is.na(df$hourBRT),]
+ df$dial_phase <- with(df, ifelse(sun >= 6.0, "day",
+ ifelse(sun < 6.0 & sun > -12.0 & hourBRT > 3, "dawn",
+ ifelse(sun <= -12.0, "night",
+ ifelse(sun < 6.0 & sun > -12.0 & hourBRT > 16 , "dusk", NA_character_)))))
+ df
+ }
> g<-f1(df)
> table(df$dial_phase) ### dusk is missing
dawn day night
12185 46276 33593
>f1使用您提供的示例,如果您将函数f1()
定义如下:
f1<-function(df) {
#loading the necessary package
require(oce)
#getting the sun angle from local time, longitude and latitude by the correction for atmospheric refraction
df$sun <- sunAngle(df$localtime, df$lon, df$lon, useRefraction = TRUE)$altitude
#creating new column with only by hour about local time to do the next conditions
df$hourBRT <- as.POSIXlt(df$localtime)$hour
df <- df[!is.na(df$hourBRT),]
df$dial_phase <- with(df, ifelse(sun >= 6.0, "day",
ifelse(sun <= -12.0, "night",
ifelse((sun < 6.0 & sun > -12.0) & (hourBRT > 3 & hourBRT < 16), "dawn", "dusk")
)
)
)
return(df)
}
结果不一样,因为一旦变量hourBRT大于3,黎明的条件就满足了,因此没有必要对黄昏进行评估
也就是说,我宁愿使用dialphase()
中的原始代码,也不愿使用f1()
中的嵌套ifelse结构。后者的可读性显然更差,更容易出错。在这方面,您可能会发现这篇阅读文章很有趣:如果您将函数f1()
定义如下,则使用您提供的示例:
f1<-function(df) {
#loading the necessary package
require(oce)
#getting the sun angle from local time, longitude and latitude by the correction for atmospheric refraction
df$sun <- sunAngle(df$localtime, df$lon, df$lon, useRefraction = TRUE)$altitude
#creating new column with only by hour about local time to do the next conditions
df$hourBRT <- as.POSIXlt(df$localtime)$hour
df <- df[!is.na(df$hourBRT),]
df$dial_phase <- with(df, ifelse(sun >= 6.0, "day",
ifelse(sun <= -12.0, "night",
ifelse((sun < 6.0 & sun > -12.0) & (hourBRT > 3 & hourBRT < 16), "dawn", "dusk")
)
)
)
return(df)
}
结果不一样,因为一旦变量hourBRT大于3,黎明的条件就满足了,因此没有必要对黄昏进行评估
也就是说,我宁愿使用dialphase()
中的原始代码,也不愿使用f1()
中的嵌套ifelse结构。后者的可读性显然更差,更容易出错。在这方面,您可能会发现这篇阅读文章很有趣:请展示一个小的可复制示例我会尝试,稍等片刻在最后一部分,您没有使用更新(df,
并在返回原始“df”之前,我在下面发布了一个解决方案。由于没有数据,我无法测试它,但我猜测它的方向正确。我编辑了帖子,查看df是否有效,请显示一个小的可复制示例我将尝试,稍等一下在最后一部分,您没有使用更新(df,…
并在返回原始“df”之前,我在下面发布了一个解决方案。由于没有数据,我无法测试它,但我猜它的方向正确。我编辑了帖子,看看df是否有效,如果我理解正确,原始函数更好,我需要更改条件?删除变量hourBRT
对于evaluatedash
,像这样?df$dial_phase[df$sun<6.0&df$sun>-12.0&df$hourBRT>3]-12.0]不。我的意思是函数f1()
没有像dialphase()那样工作
因为在为变量hourBRT提供条件时出现了一个错误。然后我给了你我的意见:在你的情况下,dialphase()
(未经修改)比f1()
可读性更强,更不容易出错,因为没有嵌套的ifels(但这只是我的意见)。我假设您的函数dialphase()
能够完成您希望它完成的任务,没有任何错误;如果不是这样,请尝试向我们解释清楚实际的问题是什么啊!好吧!我现在明白了!谢谢!我编辑了我的帖子,添加了另一个变量DepthMean
(它的下潜行为,以及该函数为每个下潜和位置创建拨号相位)和图表代码(来自我的原始数据,而不是来自这里的示例)及其结果。使用此deptmean
变量,您也可以绘制此图。三个后续问题:1)如何计算deptmean
;2)您是否尝试过测试我的解决方案中的函数f1()
来绘制图形?3)如果是,它会改变什么吗?在您的图形中,您正在使用的函数似乎在某些情况下不起作用…1)深度均值来自卫星轨道原始数据。2)是的,发生同样的事情。。3) 是的,这正是问题所在,它们是重叠的,我不知道是因为代码还是条件,因此我认为使用if-else更好,等等。因此,如果我理解正确,原始函数更好,我需要更改条件?删除evaluatedash
的变量hourBRT
,如下所示df$dial_phase[df$sun<6.0&df$sun>-12.0&df$hourBRT>3]-12.0]否。我的意思是,函数f1()
不能作为dialphase()
工作,因为在为变量hourBRT提供条件时出现了错误。然后我给了你我的观点:在你的例子中,dialphase()
(没有修改)比f1()
更具可读性,更不容易出错,因为没有嵌套的ifels(但这只是我的观点)。我假设您的函数dialphase()
完成了您希望它完成的任务,没有任何错误;如果不是这样的话,请尽量向我们解释清楚什么是真正的问题啊好的!我现在明白了!非常感谢。我编辑了我的帖子,添加了另一个变量,deptmean
(它的下潜行为,这个函数为每个下潜和位置创建拨号相位)和图表代码(来自我的原始数据,而不是这里的示例)以及结果。使用此depthean
变量,您还可以绘制此图。三个后续问题:1)如何计算depthean
;2) 您是否尝试过测试我的解决方案中的函数f1()
,以绘制图形?3) 如果是这样,它会改变什么吗?在您的图表中,您正在使用的函数似乎在某些情况下不起作用……1)深度平均值来自卫星轨道原始数据
df$hourBRT <- as.POSIXlt(df$localtime)$hour
df <- df[!is.na(df$hourBRT),]
ggplot(df, aes(as.factor(hourBRT), DepthMean, col = dial_phase)) +
geom_boxplot() +
scale_y_log10(breaks = c(10, 50, 100, 200, 300, 400, 500, 600)) +
xlab("Hour of the day") +
ylab("Depth of Dives (m)")
f1<-function(df) {
#loading the necessary package
require(oce)
#getting the sun angle from local time, longitude and latitude by the correction for atmospheric refraction
df$sun <- sunAngle(df$localtime, df$lon, df$lon, useRefraction = TRUE)$altitude
#creating new column with only by hour about local time to do the next conditions
df$hourBRT <- as.POSIXlt(df$localtime)$hour
df <- df[!is.na(df$hourBRT),]
df$dial_phase <- with(df, ifelse(sun >= 6.0, "day",
ifelse(sun <= -12.0, "night",
ifelse((sun < 6.0 & sun > -12.0) & (hourBRT > 3 & hourBRT < 16), "dawn", "dusk")
)
)
)
return(df)
}
> dialphase(dt)
Loading required package: oce
Loading required package: gsw
Loading required package: testthat
localtime lon sun dial_phase
1: 2016-10-24 12:45:06 -39.94400 54.5839409 day
2: 2016-10-24 12:46:13 -39.94410 54.7343935 day
3: 2016-10-24 12:47:02 -39.94418 54.8437520 day
4: 2016-10-24 12:48:27 -39.94432 55.0321025 day
5: 2016-10-24 12:52:39 -39.94472 55.5801854 day
6: 2016-10-24 12:55:11 -39.94496 55.9030545 day
7: 2016-10-30 21:08:02 -40.87705 2.0214448 dusk
8: 2016-10-30 21:18:27 -40.87567 0.4274248 dusk
9: 2016-10-30 21:30:13 -40.87409 -2.2624818 dusk
10: 2016-10-24 23:27:21 -40.00234 -23.6748247 night
11: 2016-10-26 06:54:29 -40.59864 -8.4538891 dawn
> f1(dt)
localtime lon sun hourBRT dial_phase
1: 2016-10-24 12:45:06 -39.94400 54.5839409 12 day
2: 2016-10-24 12:46:13 -39.94410 54.7343935 12 day
3: 2016-10-24 12:47:02 -39.94418 54.8437520 12 day
4: 2016-10-24 12:48:27 -39.94432 55.0321025 12 day
5: 2016-10-24 12:52:39 -39.94472 55.5801854 12 day
6: 2016-10-24 12:55:11 -39.94496 55.9030545 12 day
7: 2016-10-30 21:08:02 -40.87705 2.0214448 21 dusk
8: 2016-10-30 21:18:27 -40.87567 0.4274248 21 dusk
9: 2016-10-30 21:30:13 -40.87409 -2.2624818 21 dusk
10: 2016-10-24 23:27:21 -40.00234 -23.6748247 23 night
11: 2016-10-26 06:54:29 -40.59864 -8.4538891 6 dawn