我想使用dt[, x:= y * z]
之类的东西在数据表中创建一个新列。
但是,我正在使用的y
来自另一个数据表中的元素:dt2$xxx[1]
。
但是,即使dt2$xxx[1]
与dt
中的列名匹配,R仍无法识别dt2$xxx[1]
并将其作为无法计算的因数输出。
这是一个虚拟的例子:
recipe = data.table(food = c("a", "b", "c", "d", "e", "a", "b", "c", "f", "g", "a", "c", "l", "k", "o"),
ingredient = c(rep("sugar",5), rep("water",5), rep("honey",5)),
value = c(1:15))
record = data.table(date = c(rep("2018-04-27", 10)),
a = c(sample(1:10, 10)),
b = c(sample(1:10, 10)))
record[,sugar:= recipe$food[1]*recipe$value[1] + recipe$food[2]*recipe$value[2]]
这会导致错误,指出因素无法进行计算,但是我认为recipe$food[1]
(即“ a”)将被视为record
中的一列,可以按列进行计算进入功能。
我不了解后面的类属性以及如何解决此问题,如果有人可以帮助我,那真是太棒了,谢谢!
答案 0 :(得分:1)
根据示例,可能是我们需要的
r1 <- dcast(recipe[food %in% names(record)[2:3]], ingredient ~ food)
record[, sugar := a * r1$a + b * r1$b]
有了新数据,我们可以做到
r1 <- dcast(recipe[food %in% names(record)[2:3]], ingredient ~ food, fill = 0)
for(i in seq_len(nrow(r1))) record[, (r1$ingredient[i]) :=
a * r1$a[i] + b * r1$b[i]][]
如果我们需要根据列名使其更具动态性,则有两个选择
创建一个我们需要相乘的列名向量
nm1 <- names(record)[-1]
然后使用以下方法之一
1)与Reduce/Map
for(i in seq_along(r1)) record[, (r1$ingredient[i]) := Reduce(`+`, Map(`*`, .SD,
r1[i, nm1, with = FALSE])), .SDcols = nm1][]
2)与crossprod
for(i in seq_along(r1)) record[,(r1$ingredient[i]) :=
as.vector(as.matrix(.SD) %*% unlist(r1[i, nm1, with = FALSE])), .SDcols = nm1][]