根据 R 中的元素邻接分配元素值
Assign an element value based on element adjacencies in R
我有一个包含 {0,1} 的数据框,指示产品是小型、中型还是大型。
dat <- data.frame(Sm = c(1,0,0), Med = c(0,1,0), Lg = c(0,0,1))
Sm Med Lg
1 1 0 0
2 0 1 0
3 0 0 1
我希望将 1 分配给给定行中 1 之前的 0。例如,在第 2 行中,产品是 "Med",因此我希望将 1 分配给 "Sm" 列中的 0。
分配大小是一个考虑因素,所以我正在寻找一种不使用 for 循环的矢量化方法。最终解决方案应输出以下内容:
Sm Med Lg
1 1 0 0
2 1 1 0
3 1 1 1
我尝试了以下代码的几种变体,但我能得到的最接近的是一个参差不齐的数组,它正确分配所有 1,同时删除具有合法 0 的元素。
apply(dat, 1, function(x) {
x[1:which.max(x)] <- 1
})
[1] 1 1 1
及以下,接近但没有所需的尾随 0
apply(dat, 1, function(x) {
temp <- x[1:which.max(x)]
unlist(lapply(temp, function(y) {
y <- 1
}))
})
[[1]]
Sm
1
[[2]]
Sm Med
1 1
[[3]]
Sm Med Lg
1 1 1
首先,转换为矩阵并使用max.col
得到每行1
的索引:
mat <- as.matrix(dat)
mc <- max.col(mat)
逻辑构造覆盖矩阵:
mat = +(col(mat) <= mc)
或者构造一个矩阵位置的索引来改变和改变'em:
逻辑索引
mat[col(mat) < mc] <- 1L
# or
mat[which(col(mat) < mc)] <- 1L
矩阵索引
idx <- do.call( rbind, lapply( seq_along(mc), function(i)
if (i==1L) NULL
else cbind(i,seq_len(mc[i]-1))
))
mat[idx] <- 1L
向量索引
nr <- nrow(mat)
idx <- unlist( lapply( seq_along(mc), function(i)
if (mc[i]==1L) NULL
else seq(from = i, by = nr, length.out = mc[i]-1L)
))
mat[idx] <- 1L
可以在 help("[<-")
.
找到所有三种索引方法的帮助
这会做你想做的事。
dat[which(dat$Med==1),]$Sm = 1
dat[which(dat$Lg==1),]$Med = 1
dat[which(dat$Lg==1),]$Sm = 1
我有一个包含 {0,1} 的数据框,指示产品是小型、中型还是大型。
dat <- data.frame(Sm = c(1,0,0), Med = c(0,1,0), Lg = c(0,0,1))
Sm Med Lg
1 1 0 0
2 0 1 0
3 0 0 1
我希望将 1 分配给给定行中 1 之前的 0。例如,在第 2 行中,产品是 "Med",因此我希望将 1 分配给 "Sm" 列中的 0。
分配大小是一个考虑因素,所以我正在寻找一种不使用 for 循环的矢量化方法。最终解决方案应输出以下内容:
Sm Med Lg
1 1 0 0
2 1 1 0
3 1 1 1
我尝试了以下代码的几种变体,但我能得到的最接近的是一个参差不齐的数组,它正确分配所有 1,同时删除具有合法 0 的元素。
apply(dat, 1, function(x) {
x[1:which.max(x)] <- 1
})
[1] 1 1 1
及以下,接近但没有所需的尾随 0
apply(dat, 1, function(x) {
temp <- x[1:which.max(x)]
unlist(lapply(temp, function(y) {
y <- 1
}))
})
[[1]]
Sm
1
[[2]]
Sm Med
1 1
[[3]]
Sm Med Lg
1 1 1
首先,转换为矩阵并使用max.col
得到每行1
的索引:
mat <- as.matrix(dat)
mc <- max.col(mat)
逻辑构造覆盖矩阵:
mat = +(col(mat) <= mc)
或者构造一个矩阵位置的索引来改变和改变'em:
逻辑索引
mat[col(mat) < mc] <- 1L
# or
mat[which(col(mat) < mc)] <- 1L
矩阵索引
idx <- do.call( rbind, lapply( seq_along(mc), function(i)
if (i==1L) NULL
else cbind(i,seq_len(mc[i]-1))
))
mat[idx] <- 1L
向量索引
nr <- nrow(mat)
idx <- unlist( lapply( seq_along(mc), function(i)
if (mc[i]==1L) NULL
else seq(from = i, by = nr, length.out = mc[i]-1L)
))
mat[idx] <- 1L
可以在 help("[<-")
.
这会做你想做的事。
dat[which(dat$Med==1),]$Sm = 1
dat[which(dat$Lg==1),]$Med = 1
dat[which(dat$Lg==1),]$Sm = 1