【问题标题】:R data.table user defined functionR data.table 用户定义函数
【发布时间】:2015-03-12 17:15:14
【问题描述】:

我正在从使用 R 中的 data.frame 过渡到 data.table 以获得更好的性能。转换代码的主要部分之一是将自定义函数从应用于 data.frame 应用到在 data.table 中使用。

假设我有一个简单的数据表 dt1。

x y z---header

1 9 j

4 1 n

7 1 n

我正在尝试根据 x,y,z 的值计算 dt1 中的另一个新列 我尝试了 2 种方法,它们都给出了正确的结果,但更快的一种会发出警告。因此,在我使用更快的版本转换现有代码之前,要确保警告没有严重。

(1) dt1[,a:={if((x<1) & (y>3) & (j == "n")){6} else {7}}]

(2) dt1[,a:={if((x<1) & (y>3) & (j == "n")){6} else {7}}, by = 1:nrow(x)]

版本 1 的运行速度比版本 2 快,但会发出警告“条件的长度 > 1,只会使用第一个元素” 但结果是好的。 第二个版本稍慢,但没有给出警告。 一旦我开始编写复杂的函数,我想确保第一版不会给出不稳定的结果。

请将此问题视为通用问题,以运行用户定义的函数,该函数希望访问给定行中的不同列值并计算该行的新列值。

感谢您的帮助。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    如果“x”、“y”和“z”是“dt1”的列,请尝试矢量化ifelse

    dt1[, a:=ifelse(x<1 & y >3 & z=='n', 6, 7)] 
    

    或者用 7 创建 'a',然后根据逻辑索引将 6 分配给 'a'。

    dt1[, a := 7][x<1 & y >3 & z=='n', a:=6][]
    

    使用函数

    getnewvariable <- function(v1, v2, v3){
       ifelse(v1 <1 & v2 >3 & v3=='n', 6, 7)
    }
    
     dt1[, a:=getnewvariable(x,y,z)][]
    

    数据

    df1 <- structure(list(x = c(0L, 1L, 4L, 7L, -2L), y = c(4L, 9L, 1L, 
    1L, 5L), z = c("n", "j", "n", "n", "n")), .Names = c("x", "y", 
    "z"), class = "data.frame", row.names = c(NA, -5L))
    
    dt1 <- as.data.table(df1) 
    

    【讨论】:

    • 谢谢阿克伦。我的问题的另一个附录。如果我想把我所有的 if/then 逻辑放在一个函数中,这样我就可以在代码的不同位置重用它,语法会是什么样子?我尝试了一些可行的方法,但我猜测的性能应该更好,可能是更好地使用 data.table。
    • @user2956863 你能用你试过的功能更新你的帖子吗
    • @user2956863 更新了一个函数
    • 像宝石一样工作,您向我介绍了矢量化语句。非常感谢 akrun。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    相关资源
    最近更新 更多