R 具有多个条件if、else或ifelse的函数

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",

我在研究潜水行为,然后我有一个功能,在数据框中创建一个新的列,每个潜水的拨号相位(白天、黎明、夜晚和黄昏)由太阳角度决定,但很明显,它们的条件相互重叠。我的真实数据帧有超过90.000行

(1) 黎明是根据相对于地平线的-12到+6度的太阳高度来分类的,在日出时,(2)黄昏是根据日落时从+6到-12度的太阳高度来分类的。(3) 白天的温度高于+6度,夜晚的温度低于-12度

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
对于evaluate
dash
,像这样?
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更好,等等。因此,如果我理解正确,原始函数更好,我需要更改条件?删除evaluate
dash
的变量
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