如果想要根据组内的前/后非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) 我想知道朱莉娅的不变类型和表演.
在哪种情况下,使复合类型不可变提高性能?文件说
在某些情况下,它们更有效.上面的Complex示例之类的类型可以有效地打包到数组中,在某些情况下,编译器可以避免完全分配不可变对象.
我真的不明白第二部分.
是否存在使复合类型不可变降低性能的情况(超出需要通过引用更改字段的情况)?我想一个例子可能是当一个不可变类型的对象被重复用作参数时,因为
具有不可变类型的对象通过复制传递(在赋值语句和函数调用中),而可变类型通过引用传递.
但是,我在一个简单的例子中找不到任何区别:
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不变的类型不慢?是否存在使用不可变类型使代码变慢的情况?
我正在编写一个函数,除其他外,将输入强制转换为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)
这是正确的方法吗?
我想在一个组中创建一个包含上一年变量值的变量.
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 …
功能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) 假设由于某种原因我需要在数据帧中循环遍历行.
我创建了一个简单的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)
你知道为什么吗?他们使用完全相同的内存量吗?
我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)
有没有一种优雅的方法来做到这一点?
我想写一个接受补充参数的版本.与初始版本的区别仅在于几行代码,可能在循环内.典型的例子是使用权重向量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)
与第一个版本相比,此代码需要检查循环中每个步骤的条件,这听起来效率不高.
我确信有更好的解决方案,可能使用宏.处理这个问题的好方法是什么?
我想重新定义Stata中的内置命令.比如说我想在summarize命令后添加缺失值的数量.当我为program被调用者创建ADO文件时summarize,Stata会自动使用内置程序而不是用户编写的程序.有没有办法改变这种行为?