dummies = matrix(c(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), nrow=6, ncol=6)
colnames(dummies) <- c("a","b", "c", "d", "e", "f")
我有一个带假人的矩阵
> dummies
a b c d e f
[1,] 0 0 0 0 1 0
[2,] 0 0 1 0 0 0
[3,] 1 0 0 0 0 0
[4,] 0 0 0 0 0 1
[5,] 0 1 0 0 0 0
[6,] 0 0 0 1 0 0
我知道我的假人是相关的,因为第1行被分为2,3和4,以及5和6.我想在同一行中的每个虚拟代码(1)之间拆分同一行:
> dummies
a b c d e f
[1,] 0.0 0.0 -0.5 0.0 0.5 0.0
[2,] 0.0 0.0 0.5 0.0 -0.5 0.0
[3,] 0.5 0.0 0.0 0.0 0.0 -0.5
[4,] -0.5 0.0 0.0 0.0 0.0 0.5
[5,] 0.0 0.5 0.0 -0.5 0.0 0.0
[6,] 0.0 -0.5 0.0 0.5 0.0 0.0
为实现这一目标,我将执行以下操作:
dummies <- ifelse(dummies==1, 0.5, 0)
for (i in 1:nrow(dummies)){
column = which(dummies[i,] %in% 0.5)
if (i %% 2 != 0) {
dummies[i+1, column] <- -0.5
} else {
dummies[i-1, column] <- -0.5
}
}
我的问题是我是否可以用矢量化代码实现这一点。在这种情况下,我无法弄清楚如何使用ifelse
因为我无法将它与行索引结合起来在每一行上找到0.5
。
答案 0 :(得分:12)
以下是基地R的一次尝试
which
此解决方案使用矩阵只是具有维度属性的向量这一事实。 c(1, -1)[(ones %% 2 == 0L) + 1L]
在基础向量中找到1的位置。
第二行中的第二项,# get locations of ones
ones <- which(dummies == 1)
# get adjacent locations
news <- ones + c(1L, -1L)[(ones %% 2 == 0L) + 1L]
允许选择&#34;对#34;根据原始位置是偶数还是奇数,将用于分割1值的向量元素。这可以在这里工作,因为存在偶数行,这在配对元素的问题中是必需的。
下一行根据元素最初是一(0.5)还是相邻的对元素(-0.5)填充矩阵。请注意,第二个命令利用基础向量位置概念。
第二种方法借鉴了hubertl,thelatemail和martin-morgan的帖子和评论的概念,首先在正确的位置从原始矩阵中减去0.5以获得与上述相同的索引
[<-
然后将dummies[c(ones, news)] <- dummies[c(ones, news)] - .5
dummies
a b c d e f
[1,] 0.0 0.0 -0.5 0.0 0.5 0.0
[2,] 0.0 0.0 0.5 0.0 -0.5 0.0
[3,] 0.5 0.0 0.0 0.0 0.0 -0.5
[4,] -0.5 0.0 0.0 0.0 0.0 0.5
[5,] 0.0 0.5 0.0 -0.5 0.0 0.0
[6,] 0.0 -0.5 0.0 0.5 0.0 0.0
与减法结合起来
{{1}}
答案 1 :(得分:6)
创建一个指示行组grp
的向量,并从该组的每个成员中减去该组意味着rowsum(dummies, grp) / 2
grp = rep(seq_len(nrow(dummies) / 2), each=2)
dummies - rowsum(dummies, grp)[grp,] / 2
更一般地说,允许不同大小和无序的组
dummies - (rowsum(dummies, grp) / tabulate(grp))[grp,]
答案 2 :(得分:5)
这是另一种方法:
dummies[] <- sapply(split(dummies, gl(length(dummies)/2,2)), function(v) if(any(!!v))v-.5 else v)
a b c d e f
[1,] 0.0 0.0 -0.5 0.0 0.5 0.0
[2,] 0.0 0.0 0.5 0.0 -0.5 0.0
[3,] 0.5 0.0 0.0 0.0 0.0 -0.5
[4,] -0.5 0.0 0.0 0.0 0.0 0.5
[5,] 0.0 0.5 0.0 -0.5 0.0 0.0
[6,] 0.0 -0.5 0.0 0.5 0.0 0.0
答案 3 :(得分:4)
另一种方法:
dummies - ((dummies[c(1,3,5),]+dummies[c(2,4,6),])/2)[c(1,1,2,2,3,3),]
a b c d e f
[1,] 0.0 0.0 -0.5 0.0 0.5 0.0
[2,] 0.0 0.0 0.5 0.0 -0.5 0.0
[3,] 0.5 0.0 0.0 0.0 0.0 -0.5
[4,] -0.5 0.0 0.0 0.0 0.0 0.5
[5,] 0.0 0.5 0.0 -0.5 0.0 0.0
[6,] 0.0 -0.5 0.0 0.5 0.0 0.0