小编Mat*_*hew的帖子

在data.table中按组填写缺失值

如果想要根据组内的前/后非NA观察填充变量的缺失值,则data.table命令为

setkey(DT,id,date)
DT[, value_filled_in := DT[!is.na(value), list(id, date, value)][DT[, list(id, date)], value, roll = TRUE]]
Run Code Online (Sandbox Code Playgroud)

这很复杂.这是一个耻辱,因为它roll是一个非常快速和强大的选项(特别是与应用zoo::na.locf每个组内的功能相比)

我可以写一个便利函数来填补缺失的值

   fill_na <-  function(x , by = NULL, roll =TRUE , rollends= if (roll=="nearest") c(TRUE,TRUE)
             else if (roll>=0) c(FALSE,TRUE)
             else c(TRUE,FALSE)){
    id <- seq_along(x)
    if (is.null(by)){
      DT <- data.table("x" = x, "id" = id, key = "id") 
      return(DT[!is.na(x)][DT[, list(id)], x, roll = roll, rollends = rollends, allow.cartesian = TRUE])

    } else{
      DT <- data.table("x" = x, "by" = by, "id" …
Run Code Online (Sandbox Code Playgroud)

r data.table

15
推荐指数
2
解决办法
5223
查看次数

不可改变的类型和表演

我想知道朱莉娅的不变类型和表演.

  1. 在哪种情况下,使复合类型不可变提高性能?文件说

    在某些情况下,它们更有效.上面的Complex示例之类的类型可以有效地打包到数组中,在某些情况下,编译器可以避免完全分配不可变对象.

    我真的不明白第二部分.

  2. 是否存在使复合类型不可变降低性能的情况(超出需要通过引用更改字段的情况)?我想一个例子可能是当一个不可变类型的对象被重复用作参数时,因为

    具有不可变类型的对象通过复制传递(在赋值语句和函数调用中),而可变类型通过引用传递.

    但是,我在一个简单的例子中找不到任何区别:

    abstract MyType
    
    type MyType1 <: MyType
        v::Vector{Int}
    end
    
    immutable MyType2 <: MyType
        v::Vector{Int}
    end
    
    
    g(x::MyType) = sum(x.v)
    
    function f(x::MyType)
        a = zero(Int)
        for i in 1:10_000
            a += g(x)
        end
        return a
    end
    
    x = fill(one(Int), 10_000)
    x1 = MyType1(x)
    @time f(x1)
    # elapsed time: 0.030698826 seconds (96 bytes allocated)
    x2 = MyType2(x)
    @time f(x2)
    # elapsed time: 0.031835494 seconds (96 bytes allocated)
    
    Run Code Online (Sandbox Code Playgroud)

    那么为什么f不变的类型不慢?是否存在使用不可变类型使代码变慢的情况?

julia

15
推荐指数
1
解决办法
637
查看次数

在函数内部使用setDT

我正在编写一个函数,除其他外,将输入强制转换为data.table.

library(data.table)
df <- data.frame(id = 1:10)
f <- function(df){setDT(df)}
f(df)
df[, temp := 1]
Run Code Online (Sandbox Code Playgroud)

但是,最后一个命令输出以下警告:

警告消息:在[.data.table(DF, :=(温度,1)):检测到并通过取整个表的副本固定无效.internal.selfref使得:=可以通过参考添加此新列.在较早的时候,此data.table已被R复制(或使用structure()或类似方法手动创建).避免使用键< - ,名称< - 和attr < - 当前(并且奇怪地)在R中可以复制整个data.table.使用set*语法来避免复制:?set,?setnames和?setattr.另外,在R <= v3.0.2中,列表(DT1,DT2)复制了整个DT1和DT2(用于复制命名对象的R列表()); 如果是咬人,请升级到R> v3.0.2.如果此消息没有帮助,请向datatable-help报告,以便修复根本原因.

我正在使用data.table和R 3.1.1的v1.9.3.这是否意味着df在某些时候复制?如何避免这种警告?

编辑:setDT实际使用NSE 的代码.所以这似乎有效:

df1 <- data.frame(id = 1:10)
f <- function(df){eval(substitute(setDT(df)),parent.frame())}
f(df1)
df1[, temp := 1]
Run Code Online (Sandbox Code Playgroud)

看来我可以做其他的东西在函数内DF f

df1 <- data.frame(id = 1:10)
f <- function(df){
      eval(substitute(setDT(df)),parent.frame())
      df[, temp := 1]
      }
f(df1)
Run Code Online (Sandbox Code Playgroud)

这是正确的方法吗?

r data.table

13
推荐指数
1
解决办法
2955
查看次数

在R中的不平衡面板数据中创建滞后变量

我想在一个组中创建一个包含上一年变量值的变量.

     id   date        value
1     1   1992          4.1  
2     1     NA          4.5  
3     1   1991          3.3  
4     1   1990          5.3  
5     1   1994          3.0  
6     2   1992          3.2  
7     2   1991          5.2  
Run Code Online (Sandbox Code Playgroud)

value_lagged当组中缺少前一年时应该丢失 - 要么是因为它是组内的第一个日期(如第4,7行),要么是因为数据中存在年份缺口(如第5行).此外,value_lagged当缺少当前时间时应丢失(如第2行).

这给出了:

     id   date    value    value_lagged  
1     1   1992      4.1             3.3
2     1     NA      4.5              NA
3     1   1991      3.3             5.3
4     1   1990      5.3              NA
5     1   1994      3.0              NA
6     2   1992      3.2             5.2
7     2   1991      5.2              NA
Run Code Online (Sandbox Code Playgroud)

现在,在R中,我使用data.table …

r panel-data dplyr data.table

12
推荐指数
3
解决办法
4589
查看次数

"通过引用更新"vs浅拷贝

功能set或表达:=[.data.table意味着data.table通过引用更新.我不太了解的是这种行为与将操作结果重新分配给原始data.frame的方式不同.

keepcols<-function(DF,cols){
  eval.parent(substitute(DF<-DF[,cols,with=FALSE]))  
}
keeprows<-function(DF,i){
   eval.parent(substitute(DF<-DF[i,]))
}
Run Code Online (Sandbox Code Playgroud)

因为表达式中的RHS <-是最近版本的R中初始数据帧的浅表副本,所以这些函数看起来非常有效.这个基本R方法与data.table等价物有何不同?差异仅与速度或内存使用有关吗?什么时候差异最大?

一些(速度)基准.当数据集只有两个变量时,速度差异似乎可以忽略不计,并且随着更多变量变大.

library(data.table)

# Long dataset
N=1e7; K=100
DT <- data.table(
  id1 = sample(sprintf("id%03d",1:K), N, TRUE),     
   v1 =  sample(5, N, TRUE)                                         
)
system.time(DT[,a_inplace:=mean(v1)])
 user  system elapsed 
 0.060   0.013   0.077 
system.time(DT[,a_inplace:=NULL])
 user  system elapsed 
0.044   0.010   0.060 


system.time(DT <- DT[,c(.SD,a_usual=mean(v1)),.SDcols=names(DT)])
user  system elapsed 
0.132   0.025   0.161  
system.time(DT <- DT[,list(id1,v1)])
user  system elapsed 
0.124   0.026   0.153 


# Wide dataset
N=1e7; K=100
DT <- data.table(
  id1 = sample(sprintf("id%03d",1:K), …
Run Code Online (Sandbox Code Playgroud)

r data.table

10
推荐指数
1
解决办法
1285
查看次数

循环遍历数据框中的行

假设由于某种原因我需要在数据帧中循环遍历行.

我创建了一个简单的data.frame

df <- data.frame(id = sample(1e6, 1e7, replace = TRUE))
Run Code Online (Sandbox Code Playgroud)

似乎f2比f1慢得多,而我预计它们是等价的.

f1 <- function(v){
        for (obs in 1:(1e6) ){
            a <- v[obs] 
        }
        a
    }
system.time(f1(df$id))

f2 <- function(){
        for (obs in 1:(1e6) ){
            a <- df$id[obs] 
        }
    a
    }
system.time(f2())
Run Code Online (Sandbox Code Playgroud)

你知道为什么吗?他们使用完全相同的内存量吗?

performance r

8
推荐指数
1
解决办法
463
查看次数

避免 dplyr 中向量和变量名之间的冲突

dplyr在一个将 data.framedf作为参数的函数中使用。

在某些时候,我想根据我刚刚创建的名为n. 但是,如果n它也是输入 data.frame 中变量的名称,则这将不起作用。

library(dplyr)
df <- data.frame(n = c(0L, 0L))
n <- c(1L, 1L)
filter(df, n == 1L)
#> [1] n
#> <0 rows> (or 0-length row.names)
Run Code Online (Sandbox Code Playgroud)

由于该函数应该适用于任何数据框,我想避免这种情况。我尝试使用与全局环境关联的公式/惰性对象,但这返回了相同的结果:

a <- ~ n == 1L
filter_(df, a)
#> [1] n
#> <0 rows> (or 0-length row.names)
a <- lazy(n == 1L)
filter_(df, a)
#> [1] n
#> <0 rows> (or 0-length row.names)
Run Code Online (Sandbox Code Playgroud)

有没有一种优雅的方法来做到这一点?

r lazy-evaluation dplyr

5
推荐指数
1
解决办法
435
查看次数

只需几处更改即可定义新方法

我想写一个接受补充参数的版本.与初始版本的区别仅在于几行代码,可能在循环内.典型的例子是使用权重向量w.

一种解决方案是完全重写新功能

function f(Vector::a)
   ...
   for x in a
      ...
      s += x[i]
      ... 
   end
   ...
end

function f(a::Vector, w::Vector)
   ... 
   for x in a
     ...
     s += x[i] * w[i]
     ...
   end
   ...
end
Run Code Online (Sandbox Code Playgroud)

此解决方案复制代码,因此使程序更难维护.我可以拆分...成两个函数调用的不同辅助函数,但结果代码很难遵循

另一种解决方案是只编写一个函数,并? :为每个应该更改的行使用一个结构

function f(a, w::Union(Nothing, Vector) = nothing)
   ....
   for x in a
      ...
      s += (w == nothing)? x[i] : x[i] * w[i]
      ...
   end
   ....
end
Run Code Online (Sandbox Code Playgroud)

与第一个版本相比,此代码需要检查循环中每个步骤的条件,这听起来效率不高.

我确信有更好的解决方案,可能使用宏.处理这个问题的好方法是什么?

julia

5
推荐指数
1
解决办法
224
查看次数

编写与内置Stata命令同名的用户命令

我想重新定义Stata中的内置命令.比如说我想在summarize命令后添加缺失值的数量.当我为program被调用者创建ADO文件时summarize,Stata会自动使用内置程序而不是用户编写的程序.有没有办法改变这种行为?

stata

0
推荐指数
1
解决办法
151
查看次数

标签 统计

r ×6

data.table ×4

dplyr ×2

julia ×2

lazy-evaluation ×1

panel-data ×1

performance ×1

stata ×1