用R语言的data.table从另一个data.table替换索引值

5

你好,仍在努力理解data.table。如果我有一个以下所示的值的data.table,替换这些值为另一个data.table中的值,最有效的方法是什么?

set.seed(123456)

a=data.table(
  date_id = rep(seq(as.Date('2013-01-01'),as.Date('2013-04-10'),'days'),5),
  px =rnorm(500,mean=50,sd=5),
  vol=rnorm(500,mean=500000,sd=150000),
  id=rep(letters[1:5],each=100)
  )

b=data.table(
  date_id=rep(seq(as.Date('2013-01-01'),length.out=600,by='days'),5),
  id=rep(letters[1:5],each=600),
  px=NA_real_,
  vol=NA_real_
  )

setkeyv(a,c('date_id','id'))
setkeyv(b,c('date_id','id'))

我尝试的是用a中的px和vol替换b中的px和vol,其中date_idid匹配。我有些困惑 - 我认为可能需要类似于以下内容的方式,但我不认为这在实践中会起作用。
b[which(b$date_id %in% a$date_id & b$id %in% a$id),list(px:=a$px,vol:=a$vol)]

编辑

我尝试了以下方法:

t = a[b,roll=T]
t[!is.na(px),list(px.1:=px,vol.1=vol),by=list(date_id,id)]

并且收到了错误信息

Error in `:=`(px.1, px) : 
  := is defined for use in j only, and (currently) only once; i.e., DT[i,col:=1L] and DT[,newcol:=sum(colB),by=colA] are ok, but not DT[i,col]:=1L, not DT[i]$col:=1L and not DT[,{newcol1:=1L;newcol2:=2L}]. Please see help(":="). Check is.data.table(DT) is TRUE.

1
我认为解决这个问题的方法是使用快速滚动连接。这将基于关键字将列连接到表格中,如 b <- b[a,roll=T]。如果您不想要原始的 NA 列,可以在此之后直接删除它们,尽管可能有更好的一步解决方法。 - Simon O'Hanlon
感谢@SimonO101,实际上,b是一个非常大的数组,每天都会逐步填充。我需要保留b中剩余的值。 - Tahnoon Pasha
如果您每天都在更新某些内容,那么您不应该使用数据库管理系统吗?有一些软件包(我认为)允许您从R中访问数据库:postgresql和RMySQL。 - Frank
1
谢谢@Frank,这就是我想要信息的位置。这是后备数据,然后每个新的数据块都打算传输到一个postgres数据库中。我无法控制传输介质,这可能是具有稍微可变格式的Excel表格...但愿我能够... :-) - Tahnoon Pasha
2个回答

8
如果你想替换b中的值,可以使用前缀 i.。根据版本1.7.10的新闻,现在可以在j中使用前缀i.来引用继承自i的列,这些列被x中具有相同名称的列掩盖。
b[a, `:=`(px = i.px, vol = i.vol)]

1
虽然这是一个非常聪明和出色的答案,但我会选择更长的路线并执行以下操作:merge(a, b, by=c("date_id","id"), all=TRUE),然后重命名并检查结果。 - geneorama

2

根据您的描述,似乎您不需要使用roll,而当您遇到错误时,您可能想要执行以下操作:

t[!is.na(px),`:=`(px.1=px,vol.1=vol),by=list(date_id,id)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接