【问题标题】:Warning message using if function in data.table在 data.table 中使用 if 函数的警告消息
【发布时间】:2018-05-25 16:35:12
【问题描述】:

我有一个包含函数 IF 的自定义函数。当我在 data.table 中使用该函数时,我收到一条警告说 “条件的长度 > 1,并且只使用第一个元素”。

我认为该功能可能会根据需要应用于列中的所有行而不是一次一行,但我不确定。

有人知道为什么会出现这个警告吗?

我的功能是:

HeatIndex<-function(TempC,RH)
{
TFarheit= TempC * 1.8 + 32
if( TFarheit <80  ) {
   Te=TempC /15
   HI = Te/15
} else {
   TA=TempC /11
   HI = TA/125
}
HI= (HI - 32) / 1.8
return(HI )
}

数据样本:

HeatINDEX=data.table(Ave_MeanRH=c(0,100), Ave_MeanT=c(10,20))   #create data.table

并将函数应用于数据

HeatINDEX[,HI:=HeatIndex(HeatINDEX$Ave_MeanT, HeatINDEX$Ave_MeanRH)]     

【问题讨论】:

  • “快速”解决方案是指定您希望它应用于by 中的每一行:HeatINDEX[,HI:=HeatIndex(Ave_MeanT, Ave_MeanRH), by = 1:nrow(HeatINDEX)]
  • 通常最好使用ifelse 进行此类比较,而不是if。见stackoverflow.com/questions/17252905/else-if-vs-ifelse
  • 使用“by”参数仍然保持警告。在更大的数据库中,将函数运行到所有行需要很长时间

标签: r function data.table sapply


【解决方案1】:

按照 cmets 中的建议,您可以使用 ifelse() 对热量指数函数进行矢量化处理。这肯定会比逐行计算更快,这是 cmets 中建议的另一种解决方案。

# Vectorized version of function:
computeHI = function(T_cel, RH) {
    T_far = T_cel * 1.8 + 32
    HI = ifelse(test=T_far < 80, 
                 yes=(T_cel / 15) / 15, 
                  no=(T_cel / 11) / 125)
    HI = (HI - 32) / 1.8
    return(HI)
}

HeatINDEX[,HI:=HeatIndex(Ave_MeanT, Ave_MeanRH), by=seq(2)]
HeatINDEX[,vectorized_HI:=computeHI(Ave_MeanT, Ave_MeanRH)]

HeatINDEX
#    Ave_MeanRH Ave_MeanT        HI vectorized_HI
# 1:          0        10 -17.75309     -17.75309
# 2:        100        20 -17.72840     -17.72840

【讨论】:

  • 我想知道您是否可以通过避免 C -> F 和 F -> C 转换来进一步加快速度?
  • 请注意,这些计算出的热量指数数字似乎没有任何意义。您可能需要仔细检查数学!但至少你现在知道如何向量化了。
  • 该函数只是一个演示错误的演示。由于某种原因,使用 ifelse 时,计算仅应用于第一行
  • 如果不检查输入的 data.table 和列,很难说问题出在哪里。我发布的答案中的小例子可以按预期工作。
  • 是的,它运行良好。我在 && 中使用了另一个条件,忘记了 ifelse 只喜欢一个 &,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-31
  • 2019-09-05
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多