2

(Edited)

I am using the following code to create two columns in a data.table and update them with some numbers:

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]
}

I expected that this code would add two columns to the data.table T (Init_1 and Init_2) and fill them with numbers : (1:100) and (2,4,...200) respectively.

However, the code returns constant values:

     > 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
.................

Could you explain why my code is not working as expected and how it could be fixed?

Your advice will be appreciated.


Edit:

In relation to answer 2, eventually I want to use a function inside the for loop. More specifically:

# 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]]
}

or

   for (i in 1:100){
      T[, ':=' (Init_1 = R(P, i)[1,1],
                Init_2 = R(P, i)[2,1]) ]
    }
rf7
  • 1,993
  • 4
  • 21
  • 35
  • 1
    You can't add rows in place in data.table, see [here](http://stackoverflow.com/questions/16792001/add-a-row-by-reference-at-the-end-of-a-data-table-objec) – David Arenburg May 13 '17 at 22:57
  • what's the := for? – drbombe May 14 '17 at 00:00
  • In data.table := enables adding/updating columns. E.g. DT[, c("V1","V2") := list(round(exp(V1),2), LETTERS[4:6])] (from "The official Cheat Sheet for the DataCamp course") – rf7 May 14 '17 at 00:09

2 Answers2

1

I'm no data.table expert. But I know it throws helpful error messages. If you e.g. create an empty data.table and try to use := to add columns, it says

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.

Your problem might be related. Because data.table(numeric()) or rather T <- data.table(numeric(length = 0)) creates a a 0-row data.table. The empty column gets named V1 by default. Here you could use := to add empty columns. However, that's not what you want.

Instead you could do

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

Although that's pretty ugly und probably super unefficient.

lukeA
  • 53,097
  • 5
  • 97
  • 100
0

First, you should not define a function with name as T. T is reserved for TRUE in logic. Also, it is not recommended to use i for iteration since it is also used for complex number, for example

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

Third, iteration is slow in R. We should avoid to use iteration whenever possible.

Here are the simple codes to generate such matrix. Hope this helps.

T.data <- matrix(NA,nrow=100,ncol=2);
T.data[,1] <- 1:100;
T.data[,2] <- 2*T.data[,1]
drbombe
  • 609
  • 7
  • 15
  • 2
    OP is working with a data.table and not a matrix. Also, your first two points are a matter of coding style at most. Using i as the iterator is standard and there is no conflict with complex numbers as the parser can distinguish a single i from e.g. 1i. If you develop the recommended habit of always writing logical values as TRUE and FALSE there is also no problem with redefining T. – Roland May 14 '17 at 06:34