How about a bit of melt and dcast magic. This converts the data to "long" format and then back to the original "wide".
First, melt the variable on an ID:
# make an ID variable
dt[, idvar := 1:nrow(dt)]
# melt the data on the ID variable
dt2 <- melt(dt, "idvar")
Then do the division by mean operation, on each group:
# use data.table by = to do a fast division by group mean
dt2[, divByMean := value / mean(value), by = variable]
dt2
## idvar variable value divByMean
## 1: 1 V1 15 0.2859867
## 2: 2 V1 92 1.7540515
## 3: 3 V1 27 0.5147760
## 4: 4 V1 7 0.1334604
## 5: 5 V1 18 0.3431840
## ---
## 3996: 96 V40 54 1.1111111
## 3997: 97 V40 51 1.0493827
## 3998: 98 V40 23 0.4732510
## 3999: 99 V40 8 0.1646091
## 4000: 100 V40 11 0.2263374
Then back to the original wide format:
# now dcast back to "wide"
dt3 <- dcast(dt2, idvar ~ variable, mean, value.var = "divByMean")
dt3[1:5, 1:5]
## idvar V1 V2 V3 V4
## 1 1 0.2859867 0.6913303 0.2110919 1.6156624
## 2 2 1.7540515 0.7847534 0.5948954 1.8817715
## 3 3 0.5147760 0.2615845 0.8827480 0.4181715
## 5 5 0.3431840 0.3550075 0.3646133 0.3231325
## 4 4 0.1334604 1.7937220 1.3241220 1.3685611