data.table操作是否应该在函数调用中具有全局范围?

时间:2013-10-08 18:24:47

标签: r data.table

library(data.table)

DT = data.table(iris)

将虹膜数据作为data.table

str(DT)
> Classes ‘data.table’ and 'data.frame':  150 obs. of  5 variables:
>  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... 
>  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
>  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... 
>  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... 
>  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1
>  - attr(*, ".internal.selfref")=<externalptr>

这只是一个简单的功能,通过删除因子列来添加虹膜的数字部分。

myfun = function(dt){
    dt[,Species:=NULL]
    return(sum(dt))
}

运行功能

myfun(DT)  
> [1] 2078.7

现在DT缺少全局环境中的Species列

str(DT)
> Classes ‘data.table’ and 'data.frame':  150 obs. of  4 variables:
>  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
>  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
>  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
>  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
>  - attr(*, ".internal.selfref")=<externalptr>

2 个答案:

答案 0 :(得分:3)

data.table以引用方式工作。这就是它如此快速和有用的原因。

但这也意味着在函数中传递参数时必须小心。如果您没有传递副本,则将更改原始对象。

myfun = function(dt){
    # Use something like this
    dt <- copy(dt)    <~~~~~ KEY LINE
    dt[,Species:=NULL]
    return(sum(dt))
}

或者,您可以在调用函数时调用copy

 myfun(copy(DT))

但我认为这会给错误留下太多空间。

答案 1 :(得分:0)

这是一个副本,通过搜索找到:[r] select columns data.table

任何这些工作:

> sum(DT[,!colnames(DT) %in% "Species" ,with=FALSE])
[1] 2078.7
> sum(DT[,1:4 ,with=FALSE])
[1] 2078.7
> sum(DT[,-5 ,with=FALSE])
[1] 2078.7
> sum(DT[,-which(colnames(DT)=="Species") ,with=FALSE])
[1] 2078.7

'Species'仍在DT中。