基于涉及查找表的公式创建新列

时间:2017-01-07 16:14:22

标签: r data.table

我有一个像这样的查找表:

0 1 2 3 4 5 6 7 8 9 h H k K m M b B   + - ? 
0 1 2 3 4 5 6 7 8 9 2 2 3 3 6 6 9 9 0 0 0 0  

使用此代码构建

symbols <- c("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "h", "H", "k", "K", "m", "M", "b", "B","", "+", "-", "?")
exp <- c(seq(0,9),2,2,3,3,6,6,9,9,0,0,0,0)
names(exp) <- symbols

执行exp[["k]]会返回3

类的numeric

我有一个data.table noaa,其中包含2列,一列有值,另一列带有指数代码,如&#34; k&#34;或4。 此DT来自此文件:https://d396qusza40orc.cloudfront.net/repdata%2Fdata%2FStormData.csv.bz2

我想在data.table中创建一个新列TOTALVALUE,例如值为(下面是伪代码中的公式)

noaa$TOTALVALUE = noaa$VALUE*10^exp[[noaa$EXPONENT]] in which noaa$EXPONENT value is matched using the exp matching table

我尝试了以下代码

noaa$test <- with(noaa, PROPDMG*10^exp[[PROPDMGEXP]])

我得到了

Error in exp[[PROPDMGEXP]] : 
       attempt to select more than one element in vectorIndex

如果我删除[]中的一个,那么它会进入无限循环并崩溃。

实现这一目标的最佳方法是什么?我到目前为止提出的其他选择是将exp构建为数据框并使用匹配,或构建函数并使用lapply

2 个答案:

答案 0 :(得分:3)

您的问题是,您尝试使用[[进行矢量化选择,但[[ 总是只选择一个元素。您可以切换到[来解决问题:

x = 1:3
names(x) = letters[1:3]
# x
# a b c 
# 1 2 3 

x[["a"]]
# [1] 1

x[[c("a", "c")]]
# Error in x[[c("a", "c")]] : 
#   attempt to select more than one element in vectorIndex

x["a"]
# a
# 1

# x[c("a", "c")]
# a c 
# 1 3 

正如评论者指出的那样,最佳做法是使用:=向data.table添加列 - 使用<-代替:=将错过data.table的大部分内容。效率。 Akrun建议使用以下这条线是完美的:

noaa[, TOTALVALUE := VALUE * 10 ^ exp[EXPONENT]]

答案 1 :(得分:1)

除了

symbols <- c("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "h", "H", "k", "K", "m", "M", "b", "B","", "+", "-", "?")
expValue <- c(seq(0,9),2,2,3,3,6,6,9,9,0,0,0,0)
expTable <- data.frame(symbols, expValue)

运作良好,但速度很慢,以下方法有效,而且速度更快。

我没有构建命名向量,而是构建了一个包含2列的数据框:

noaa[, PROPDGMGVALUE := PROPDMG * 10 ^ expTable[match(PROPDMGEXP, expTable$symbols),2]]
noaa[, PROPDGMGVALUE := CROPDMG * 10 ^ expTable[match(CROPDMGEXP, expTable$symbols),2]]

然后我使用match找到值,并在最后创建我需要的两列

system.time(noaa[, pouet :=  PROPDMG*10^expValue[PROPDMGEXP]])
   user  system elapsed 
   223.11    0.03  223.28 

system.time(noaa[, PROPDGMGVALUE := PROPDMG * 10 ^ expTable[match(PROPDMGEXP, expTable$symbols),2]])
    user  system elapsed 
    0.04    0.00    0.04 

结果超过900k行,8列DT

<iframe width="560" height="315" src="http://pakvim.com/embed/nCE4UUPxO_s" frameborder="0" allowfullscreen></iframe>