如何进行逐行减法并将特定数字替换为零?

发布于 2024-12-07 01:18:03 字数 657 浏览 0 评论 0原文

步骤1:我有一个像这样的简化数据框:

df1 = data.frame (B=c(1,0,1), C=c(1,1,0)
  , D=c(1,0,1), E=c(1,1,0), F=c(0,0,1)
  , G=c(0,1,0), H=c(0,0,1), I=c(0,1,0))

  B C D E F G H I
1 1 1 1 1 0 0 0 0
2 0 1 0 1 0 1 0 1
3 1 0 1 0 1 0 1 0

步骤2:我想做逐行减法,即(row1 - row2)、(row1 - row3)和(row2 - row3)

row1-row2    1  0    1  0    0  -1   0  -1
row1-row3    0  1    0  1   -1   0  -1   0
row2-row3   -1  1   -1  1   -1   1  -1   1

步骤3:将所有-1替换为0

row1-row2   1   0   1   0   0   0   0   0
row1-row3   0   1   0   1   0   0   0   0
row2-row3   0   1   0   1   0   1   0   1

可以你介意教我怎么做吗?

Step 1: I have a simplified dataframe like this:

df1 = data.frame (B=c(1,0,1), C=c(1,1,0)
  , D=c(1,0,1), E=c(1,1,0), F=c(0,0,1)
  , G=c(0,1,0), H=c(0,0,1), I=c(0,1,0))

  B C D E F G H I
1 1 1 1 1 0 0 0 0
2 0 1 0 1 0 1 0 1
3 1 0 1 0 1 0 1 0

Step 2: I want to do row wise subtraction, i.e. (row1 - row2), (row1 - row3) and (row2 - row3)

row1-row2    1  0    1  0    0  -1   0  -1
row1-row3    0  1    0  1   -1   0  -1   0
row2-row3   -1  1   -1  1   -1   1  -1   1

step 3: replace all -1 to 0

row1-row2   1   0   1   0   0   0   0   0
row1-row3   0   1   0   1   0   0   0   0
row2-row3   0   1   0   1   0   1   0   1

Could you mind to teach me how to do so?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

温柔女人霸气范 2024-12-14 01:18:03

我喜欢使用 plyr 库来完成类似的事情,使用 combn 函数生成所有可能的行/列对。

require(plyr)
combos <- combn(nrow(df1), 2)

adply(combos, 2, function(x) {
  out <- data.frame(df1[x[1] , ] - df1[x[2] , ])
  out[out == -1] <- 0
  return(out)
  }
)

结果:

  X1 B C D E F G H I
1  1 1 0 1 0 0 0 0 0
2  2 0 1 0 1 0 0 0 0
3  3 0 1 0 1 0 1 0 1

如有必要,您可以删除第一列,plyr 会自动为您吐出该列。

类似问题:

I like using the plyr library for things like this using the combn function to generate all possible pairs of rows/columns.

require(plyr)
combos <- combn(nrow(df1), 2)

adply(combos, 2, function(x) {
  out <- data.frame(df1[x[1] , ] - df1[x[2] , ])
  out[out == -1] <- 0
  return(out)
  }
)

Results in:

  X1 B C D E F G H I
1  1 1 0 1 0 0 0 0 0
2  2 0 1 0 1 0 0 0 0
3  3 0 1 0 1 0 1 0 1

If necessary, you can drop the first column, plyr spits that out automagically for you.

Similar questions:

风轻花落早 2024-12-14 01:18:03

作为记录,我会这样做:

cmb <- combn(seq_len(nrow(df1)), 2)
out <- df1[cmb[1,], ] - df1[cmb[2,], ]
out[out < 0] <- 0
rownames(out) <- apply(cmb, 2, 
                       function(x) paste("row", x[1], "-row", x[2], sep = ""))

这会产生(上面的最后一行是一些糖,可能不需要):

> out
          B C D E F G H I
row1-row2 1 0 1 0 0 0 0 0
row1-row3 0 1 0 1 0 0 0 0
row2-row3 0 1 0 1 0 1 0 1

这是完全矢量化的,并利用索引来扩展/提取 df1 的元素> 逐行操作所需。

For the record, I would do this:

cmb <- combn(seq_len(nrow(df1)), 2)
out <- df1[cmb[1,], ] - df1[cmb[2,], ]
out[out < 0] <- 0
rownames(out) <- apply(cmb, 2, 
                       function(x) paste("row", x[1], "-row", x[2], sep = ""))

This yields (the last line above is a bit of sugar, and may not be needed):

> out
          B C D E F G H I
row1-row2 1 0 1 0 0 0 0 0
row1-row3 0 1 0 1 0 0 0 0
row2-row3 0 1 0 1 0 1 0 1

Which is fully vectorised and exploits indices to extend/extract the elements of df1 required for the row-by-row operation.

伪装你 2024-12-14 01:18:03
> df2 <- rbind(df1[1,]-df1[2,], df1[1,]-df1[3,], df1[2,]-df1[3,])
> df2
    B C  D E  F  G  H  I
1   1 0  1 0  0 -1  0 -1
2   0 1  0 1 -1  0 -1  0
21 -1 1 -1 1 -1  1 -1  1

> df2[df2==-1] <- 0
> df2
   B C D E F G H I
1  1 0 1 0 0 0 0 0
2  0 1 0 1 0 0 0 0
21 0 1 0 1 0 1 0 1

如果您想将行的名称更改为示例中的行名称:

> rownames(df2) <- c('row1-row2', 'row1-row3', 'row2-row3')
> df2
          B C D E F G H I
row1-row2 1 0 1 0 0 0 0 0
row1-row3 0 1 0 1 0 0 0 0
row2-row3 0 1 0 1 0 1 0 1

最后,如果提前不知道行数,则可以执行以下操作:

df1 = data.frame (B=c(1,0,1), C=c(1,1,0), D=c(1,0,1), E=c(1,1,0), F=c(0,0,1), G=c(0,1,0), H=c(0,0,1), I=c(0,1,0))

n <- length(df1[,1])
ret <- data.frame()
for (i in 1:(n-1)) {
  for (j in (i+1):n) {
    diff <- df1[i,] - df1[j,]
    rownames(diff) <- paste('row', i, '-row', j, sep='')
    ret <- rbind(ret, diff)
  }
}
ret[ret==-1] <- 0
print(ret)
> df2 <- rbind(df1[1,]-df1[2,], df1[1,]-df1[3,], df1[2,]-df1[3,])
> df2
    B C  D E  F  G  H  I
1   1 0  1 0  0 -1  0 -1
2   0 1  0 1 -1  0 -1  0
21 -1 1 -1 1 -1  1 -1  1

> df2[df2==-1] <- 0
> df2
   B C D E F G H I
1  1 0 1 0 0 0 0 0
2  0 1 0 1 0 0 0 0
21 0 1 0 1 0 1 0 1

If you'd like to change the name of the rows to those in your example:

> rownames(df2) <- c('row1-row2', 'row1-row3', 'row2-row3')
> df2
          B C D E F G H I
row1-row2 1 0 1 0 0 0 0 0
row1-row3 0 1 0 1 0 0 0 0
row2-row3 0 1 0 1 0 1 0 1

Finally, if the number of rows is not known ahead of time, the following should do the trick:

df1 = data.frame (B=c(1,0,1), C=c(1,1,0), D=c(1,0,1), E=c(1,1,0), F=c(0,0,1), G=c(0,1,0), H=c(0,0,1), I=c(0,1,0))

n <- length(df1[,1])
ret <- data.frame()
for (i in 1:(n-1)) {
  for (j in (i+1):n) {
    diff <- df1[i,] - df1[j,]
    rownames(diff) <- paste('row', i, '-row', j, sep='')
    ret <- rbind(ret, diff)
  }
}
ret[ret==-1] <- 0
print(ret)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文