【问题标题】:R: Interpolate a data.table when x's are the names of columns and y's the rowsR:当 x 是列名而 y 是行时,插入 data.table
【发布时间】:2017-01-25 21:11:31
【问题描述】:

让我举例说明:

library(data.table)
A <- data.table( value = c(1.3,2.1,2.7), '1' = c(0.4,0.3,0.5), '2' = c(1.1,1.3,1.7) , '3' = c(2.1,2.4,2.6) )

> A
   value   1   2   3
1:   1.3 0.4 1.1 2.1
2:   2.1 0.3 1.3 2.4
3:   2.7 0.5 1.7 2.6

我想使用 x = 1,2,3 和 y 作为每一行来插入“值”列中的数字。

因此,对于第一行,x = 1,2,3 和 y = 0.4,1.1,2.1。应插值的值为 x0 = 1.3。以此类推下一行。我想出了以下函数来使用 data.table 按行应用它:

## Function to Interpolate
interpol <- function(dt){
  # Define X
  x <- c(1,2,3)
  # Grab each row of the data.table
  y <- as.numeric(dt[,c('1','2','3'), with = F])
  # Interpolate and get the value of Y
  approx(x,y,dt[,'value', with = F])$y
}

# Apply by row
A[, interpol(.SD), by = 1:nrow(A)]

问题在于,对于几百万行的 data.table,这似乎非常慢。优化它的最佳方法是什么?

旁注

原来我的问题是这样的:

我不得不使用不同的表 B 插入相同的 A:

A2 <- data.table(name = LETTERS[1:3], value = c(1.3,2.1,2.7))
B2 <- data.table(name = LETTERS[1:3], '1' = c(0.4,0.3,0.5), '2' = c(1.1,1.3,1.7) , '3' = c(2.1,2.4,2.6) )

> A2
   name value
1:    A   1.3
2:    B   2.1
3:    C   2.7

> B2
   name   1   2   3
1:    A 0.4 1.1 2.1
2:    B 0.3 1.3 2.4
3:    C 0.5 1.7 2.6

我决定合并这两个 data.tables 以获得上面的一个,因为我相信它会更容易。但也许为了让它运行得更快,将它们作为单独的 data.tables 可能会更好?

【问题讨论】:

  • 您可以使用melt(A[, id := .I], id=c("id", "value"))[, variable := as.numeric(variable)][, approx(variable, value.1, value[1])$y, by=id],但我并不认为它会更快。
  • @Frank 我喜欢这种方法。我不确定是否更快,但我认为它会做。请注意,我必须在 as.numeric 之前先执行 as.character,因为列名被视为一个因素。如果您将此作为答案发布,我会接受。
  • @Frank 实际上,这种方法要快得多。它似乎工作得很好。

标签: r performance data.table


【解决方案1】:

首先,我建议以长格式存储B2 数据:

dat = melt(B2, id="name", value.name = "v")
dat[, variable := as.numeric(as.character(variable))]

   name variable   v
1:    A        1 0.4
2:    B        1 0.3
3:    C        1 0.5
4:    A        2 1.1
5:    B        2 1.3
6:    C        2 1.7
7:    A        3 2.1
8:    B        3 2.4
9:    C        3 2.6

从这里,您可以加入 A2 以按组进行插值:

dat[A2, on=.(name), approx(variable, v, value)$y, by=.EACHI]

   name   V1
1:    A 0.61
2:    B 1.41
3:    C 2.33

【讨论】:

    猜你喜欢
    • 2011-06-13
    • 2015-12-02
    • 1970-01-01
    • 2020-01-29
    • 2010-11-05
    • 2015-09-04
    • 2020-08-12
    • 1970-01-01
    相关资源
    最近更新 更多