【问题标题】:Updating a data.table in R在 R 中更新 data.table
【发布时间】:2017-05-13 22:39:33
【问题描述】:

(已编辑)

我正在使用以下代码在 data.table 中创建两列并用一些数字更新它们:

T <- data.table(Init_1 = rep(0, 100), Init_2 = rep(0, 100))

for (i in 1:100){
  T[, Init_1 := i]
  T[, Init_2 := 2*i]
}

我希望这段代码会在 data.table T 中添加两列(Init_1 和 Init_2),并分别用数字填充它们:(1:100) 和 (2,4,...200)。

但是,代码返回常量值:

     > T
   Init_1 Init_2
  1:    100    200
  2:    100    200
  3:    100    200
  4:    100    200
  5:    100    200
  6:    100    200
  7:    100    200
  8:    100    200
.................

您能否解释一下为什么我的代码没有按预期工作以及如何修复它?

您的建议将不胜感激。


编辑:

关于答案 2,最终我想在 for 循环中使用一个函数。更具体地说:

# A FUNCTION THAT RETURNS THE TRANSITION PROBABILITIES AFTER N STEPS IN A MARKOV CHAIN
#-------------------------------------------------------------------------------------
R <- function(P, n){
  if (n==1) return(P)
  R(P, n-1) %*% P

}

# A ONE-STEP PROBABILITY MATRIX
#---------------------------------------------------------------------------------------
P = matrix(c(0.6, 0.1, 0.3, 0.2, 0.7, 0.1, 0.3, 0.3, 0.4), nrow = 3, byrow = TRUE)

# EXAMINING THE CONVERGENCE PROCESS OF THE PROBABILITIES OVER TIME
#########################################################################
T <- data.table(Init_1 = rep(0, 100), Init_2 = rep(0, 100))

for (i in 1:100){
  T[, Init_1 := R(P, i)[1,1]]
  T[, Init_2 := R(P, i)[2,1]]
}

   for (i in 1:100){
      T[, ':=' (Init_1 = R(P, i)[1,1],
                Init_2 = R(P, i)[2,1]) ]
    }

【问题讨论】:

  • 你不能在data.table中添加行,见here
  • := 是干什么用的?
  • 在 data.table := 中启用添加/更新列。例如。 DT[, c("V1","V2") := list(round(exp(V1),2), LETTERS[4:6])] (来自“DataCamp 课程的官方备忘单”)跨度>

标签: r data.table


【解决方案1】:

我不是 data.table 专家。但我知道它会抛出 有用的错误信息。如果你例如创建一个空的 data.table 和 尝试使用 := 添加列,它说

T <- data.table()
T[,a:=1]
# Error in `[.data.table`(T, , `:=`(a, 1)) : 
#   Cannot use := to add columns to a null data.table (no columns), currently. 
#   You can use := to add (empty) columns to a 0-row data.table (1 or more empty columns), 
#   though.

您的问题可能与此有关。因为data.table(numeric()) 或者更确切地说T &lt;- data.table(numeric(length = 0)) 创建了一个0 行的data.table。默认情况下,空列的名称为 V1。在这里你可以使用 := 添加空列。然而,这不是你想要的。

你可以这样做

T <- data.table(numeric(0))
for (i in 1:5){
  T <- T[, .(
    Init_1=if (exists("Init_1")) c(Init_1, i) else i, 
    Init_2=if (exists("Init_2")) c(Init_2, 2*i) else  2*i )]
}
T
#    Init_1 Init_2
# 1:      1      2
# 2:      2      4
# 3:      3      6
# 4:      4      8
# 5:      5     10

虽然这很丑陋,而且可能效率极低。

【讨论】:

    【解决方案2】:

    首先,您不应定义名称为 T 的函数。T 在逻辑中保留为 TRUE。此外,不建议使用 i 进行迭代,因为它也用于复数,例如

    > (2i)^2
    [1] -4+0i
    

    第三,R 中的迭代速度很慢。我们应该尽可能避免使用迭代。

    以下是生成此类矩阵的简单代码。希望这可以帮助。

    T.data <- matrix(NA,nrow=100,ncol=2);
    T.data[,1] <- 1:100;
    T.data[,2] <- 2*T.data[,1]
    

    【讨论】:

    • OP 使用的是 data.table 而不是矩阵。此外,您的前两点最多是编码风格的问题。使用 i 作为迭代器是标准的,并且与复数没有冲突,因为解析器可以将单个 i 与例如1i。如果您养成始终将逻辑值写为 TRUE 和 FALSE 的推荐习惯,那么重新定义 T 也没有问题。
    猜你喜欢
    • 2015-04-08
    • 1970-01-01
    • 2016-07-20
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 2016-02-21
    相关资源
    最近更新 更多