使用函数更新data.table子集

时间:2014-10-08 23:12:30

标签: r function data.table sapply

我有一个data.table

dt2 <- data.table(urn=1:10,freq=0, freqband="")
dt2$freqband = NA
dt2$freq <- 1:7 #does give a warning message
##    urn freq freqband
## 1:   1    1       NA
## 2:   2    2       NA
## 3:   3    3       NA
## 4:   4    4       NA
## 5:   5    5       NA
## 6:   6    6       NA
## 7:   7    7       NA
## 8:   8    1       NA
## 9:   9    2       NA
##10:  10    3       NA

我还有一个功能,我想用它来分组我的频率列

fn_GetFrequency <- function(numgifts) {
    if (numgifts <5) return("<5")
    if (numgifts >=5) return("5+")
    return("ERROR")
}

我想基于此功能设置freqband列。在某些情况下,它将是所有记录,在某些情况下,它将是一个子集。我目前的方法是(对于一个子集):

dt2[dt2$urn < 9, freqband := fn_GetFrequency(freq)]

使用这种方法我收到警告:

Warning message:
In if (numgifts < 5) return("<5") :
  the condition has length > 1 and only the first element will be used

然后它将所有记录设置为&#34;&lt; 5&#34;而不是正确的价值。我觉得我需要使用某种lapply / sapply / etc函数,但是我仍然无法完全掌握它们的工作方式,以便用它们来解决我的问题。

非常感谢任何帮助。

编辑:如果你使用需要2个参数的函数,你会怎么做?

更新:在我尝试更新后包含dt2的输出

    urn freq freqband
 1:   1    1       <5
 2:   2    2       <5
 3:   3    3       <5
 4:   4    4       <5
 5:   5    5       <5
 6:   6    6       <5
 7:   7    7       <5
 8:   8    1       <5
 9:   9    2       NA
10:  10    3       NA

更新:我尝试了这个代码并且它可以提供所需的输出,它允许我有一个我可以在其他代码处调用的函数。

dt2[dt2$urn < 9, freqband := sapply(freq, fn_GetFrequency)]

1 个答案:

答案 0 :(得分:1)

> fn_GetFrequency <- function(numgifts) {
+     ifelse (numgifts <5, "<5", "5+")
+ }
> dt2[dt2$urn < 9, freqband := fn_GetFrequency(freq)]
> dt2
    urn freq freqband
 1:   1    1       <5
 2:   2    2       <5
 3:   3    3       <5
 4:   4    4       <5
 5:   5    5       5+
 6:   6    6       5+
 7:   7    7       5+
 8:   8    1       <5
 9:   9    2       NA
10:  10    3       NA

对于多个频段(我之前确定已经问过),您应该使用findInterval功能。我正在使用data.table方式重新组合而不是数据帧方式:

dt2[ urn==8, freq := -1 ] # and something to test the <0 condition

dt2[ urn <= 8, freqband := c("ERROR", "<5", "5+")[
                                  findInterval(freq,c(-Inf, 0, 5 ,Inf))] ]
dt2
    urn freq freqband
 1:   1    1       <5
 2:   2    2       <5
 3:   3    3       <5
 4:   4    4       <5
 5:   5    5       5+
 6:   6    6       5+
 7:   7    7       5+
 8:   8   -1    ERROR
 9:   9    2       NA
10:  10    3       NA