R 高效地重复列表中的data.table,顺序替换循环中另一个data.table中同名的列
我有两个R 高效地重复列表中的data.table,顺序替换循环中另一个data.table中同名的列,r,loops,replace,data.table,updates,R,Loops,Replace,Data.table,Updates,我有两个数据。表s: x <- data.table(a = c(1, 2, 3, 4, 1), b = c(2, 3, 4, 1, 2), c = c(3, 4, 1, 2, 3)) y <- data.table(a = c(1, 0, 0, 0, 1), b = c(0, 1, 0, 0, 0), c = c(0, 0, 0, 0, 1)) 我尝试的是: z <- lapply(names(x), function(i) { x[ , i, with = FALSE
数据。表s:
x <- data.table(a = c(1, 2, 3, 4, 1), b = c(2, 3, 4, 1, 2), c = c(3, 4, 1, 2, 3))
y <- data.table(a = c(1, 0, 0, 0, 1), b = c(0, 1, 0, 0, 0), c = c(0, 0, 0, 0, 1))
我尝试的是:
z <- lapply(names(x), function(i) {
x[ , i, with = FALSE]
})
w <- rep(list(y), ncol(y))
myfun <- function(obj1, obj2) {
cbind(obj1, obj2)
}
u <- Map(myfun, obj1 = z, obj2 = w)
u <- lapply(u, function(i) {
setcolorder(i[ , unique(names(i)), with = FALSE], names(x))
})
但是,它会将第一个列表组件返回为空,并将x
的所有值复制到下一个列表组件中
有人能帮忙吗?在创建列表时,我们可能需要一份副本
“y”,而不是
w <- rep(list(y), ncol(y))
引用赋值(:=
)会更改每个循环中的列值,因为它们引用的是内存中的同一对象。在第一种情况下,赋值后,它也会更改“y”以及“w”list
元素。第二种情况下,它只能更改“w”并保留“y”,因为我们copy
ied。要了解行为,请在for
循环中执行set
赋值
for(j in seq_along(x)) {print(w[[j]][[j]])
set(w[[j]], i = NULL, j =j, x[[j]])
print("----")
print(w[[j]])
}
为了避免这种情况,请使用replicate
w <- replicate(ncol(y), copy(y), simplify = FALSE)
或基于Map
的分配
Map(function(u, v) u[, (v) := x[[v]]][], w, names(x))
#[[1]]
# a b c
#1: 1 0 0
#2: 2 1 0
#3: 3 0 0
#4: 4 0 0
#5: 1 0 1
#[[2]]
# a b c
#1: 1 2 0
#2: 0 3 0
#3: 0 4 0
#4: 0 1 0
#5: 1 2 1
#[[3]]
# a b c
#1: 1 0 3
#2: 0 1 4
#3: 0 0 1
#4: 0 0 2
#5: 1 0 3
如果我们在创建“w”时没有复制“y”对象,则可以使用来自base R
的简单Map
完成赋值,而不是通过引用赋值
Map(function(u, v) {u[[v]] <- x[[v]]
u}, w, names(x))
Map(函数(u,v){u[[v]]像往常一样,快速响应并给出详细解释。非常感谢!
w <- replicate(ncol(y), copy(y), simplify = FALSE)
for(j in seq_along(x)) {print(w[[j]][[j]])
set(w[[j]], i = NULL, j =j, x[[j]])
print("----")
print(w[[j]])
}
Map(function(u, v) u[, (v) := x[[v]]][], w, names(x))
#[[1]]
# a b c
#1: 1 0 0
#2: 2 1 0
#3: 3 0 0
#4: 4 0 0
#5: 1 0 1
#[[2]]
# a b c
#1: 1 2 0
#2: 0 3 0
#3: 0 4 0
#4: 0 1 0
#5: 1 2 1
#[[3]]
# a b c
#1: 1 0 3
#2: 0 1 4
#3: 0 0 1
#4: 0 0 2
#5: 1 0 3
Map(function(u, v) {u[[v]] <- x[[v]]
u}, w, names(x))