为何数据表整数矩阵乘法可行,浮点数版本却无法运行?
Why One Code Snippet Works, the Other Doesn't
Let’s break this down step by step, focusing on how matrix indexing rules and data.table's column iteration interact here.
The Working Code: Integer Values as Indices
First, let's look at the code that runs successfully:
a <- data.table(t(c(1, 2, 3, 4, 5))) b <- matrix(data=1, nrow=10, ncol=5) a[,lapply(.SD,function(x)(x*b[,x]))]
Here’s what’s happening:
ais a 1-row, 5-columndata.tablewhere each column holds an integer value (1, 2, 3, 4, 5).- When
lapply(.SD, ...)runs, it iterates over each column ofa. For each column,xis the single value in that column (sinceaonly has one row). b[,x]usesxas a column index for matrixb. R allows integer values to index matrix columns directly—sox=1grabs the 1st column ofb,x=2grabs the 2nd, and so on.- Multiplying
x(a single integer) byb[,x](a 10-element vector) works because R recycles the single value to match the vector length, resulting in a valid 10-element vector per column. Thedata.tablethen assembles these vectors into new columns, so the code runs without errors.
The Failing Code: Non-Integer Values as Indices
Now the code that breaks:
a <- data.table(t(c(0.1, 0.2, 0.3, 0.4, 0.5))) b <- matrix(data=1, nrow=10, ncol=5) a[,lapply(.SD,function(x)(x*b[,x]))]
The problem boils down to matrix indexing rules:
anow holds non-integer (floating-point) values (0.1, 0.2, etc.) in its columns.- When
b[,x]runs withx=0.1, R tries to use this floating-point number as a column index forb. But matrices only accept integer indices (or logical indices/column names) to reference columns—there’s no such thing as the "0.1th column" of a matrix. - R doesn’t automatically convert floating-point numbers to integers for matrix indexing here (unlike some other contexts), so this throws an invalid index error immediately.
Fixing the Failing Code
If your goal is to use the values in a as weights (not column indices), you’d want to do element-wise multiplication instead of indexing:
# Multiply each value in a by the entire matrix b (recycles rows of a to match b's rows) a[, lapply(.SD, function(x) x * b)]
If you intended to use the values in a as column indices (but they’re stored as floats), convert them to integers first:
a <- data.table(t(c(0.1, 0.2, 0.3, 0.4, 0.5))) a <- a[, lapply(.SD, as.integer)] # Convert columns to integers b <- matrix(data=1, nrow=10, ncol=5) a[, lapply(.SD, function(x) x * b[,x])] # Now runs successfully
内容的提问来源于stack exchange,提问作者Z117




