R 计算向量中下一个元素与上一个元素不同的次数

R 计算向量中下一个元素与上一个元素不同的次数,r,R,我有一个矩阵,看起来像这样: a=c(rep(0,5),rep(1,5),rep(2,5)) b=c(rep(1,5),rep(1,5),rep(2,5)) d=rbind(a,b) [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] a 0 0 0 0 0 1 1 1 1 1 2 2 2

我有一个矩阵,看起来像这样:

a=c(rep(0,5),rep(1,5),rep(2,5))
b=c(rep(1,5),rep(1,5),rep(2,5))
d=rbind(a,b)

  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
a    0    0    0    0    0    1    1    1    1     1     2     2     2     2     2
b    1    1    1    1    1    1    1    1    1     1     2     2     2     2     2
我想做的是计算一行中某个值发生变化的次数。例如,在第一行中,有两个更改—第5列到第6列,第10列到第11列

我使用
if
语句和
for
循环比较每个值,并使用计数器
c
计算发生更改的次数:

m=matrix(NA, nrow = length(d[,1]), ncol = 1)

for (s in 1:length(d[,1])){

  c=0

  for (i in 1:length(d[1,])){

    if (i < length(d[1,])){

      if (d[s,i]!=d[s,(i+1)]){
        c=c+1
      }  

    }

  }

  m[s,1]<-c
}
m=矩阵(NA,nrow=长度(d[,1]),ncol=1)
对于(1中的s:长度(d[,1])){
c=0
对于(1中的i:长度(d[1,])){
if(i<长度(d[1,])){
如果(d[s,i]!=d[s,(i+1)]){
c=c+1
}  
}
}

m[s,1]使用函数
diff

rowSums(t(apply(d,1,diff)))
或者按照Ben的建议(不确定我为什么决定,
t
rowSums

同样,我假设“1”与示例中的“1”不同,但如果数字跳跃,您可以尝试

colSums(apply(d,1,diff)!=0)

您也可以尝试以下方法:

apply(d,1,function(x) length(rle(x)$values)-1)
此函数迭代数据帧
d
的每一行。迭代通过
apply
完成,第二个参数(边距)的值为1,表示应选择行(两个边距表示列)

因此,我们将匿名函数
length(rle(x)$values)
应用于每一行,它临时存储在
x
中。根据
help(rle)
,函数执行以下操作:

计算向量中等长运行的长度和值

我们只对值感兴趣,而不是对连续运行的长度感兴趣。但事实上,我们甚至不需要知道存储在
rle(x)$values
中的值。这里我们唯一关心的是向量中有多少个值构成了“等值运行”。要提取值的数量,我们可以使用
length()
函数,该函数确定向量中的条目数。最后,由于始终至少有一个值,并且我们想知道值的变化频率,因此需要从
length()
获得的结果中减去1


希望这能有所帮助。

为了好玩,我们提供了一个带有数据表的解决方案。(在数据量巨大的情况下,可以提供更好的性能,尽管我不认为在这种情况下):

工作原理:

我只是通过将列“移动”一个来比较这两个表,结果是一个表中有真/假值,其中每个真表示与下一列相比值的变化:

> diff
        V1    V2    V3    V4    V5    V6    V7    V8    V9  V10   V11   V12   V13   V14
[1,] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
[2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
不,我可以计算
TRUE
s(R中的值为
1
,FALSE为
0
,您可以通过
as.numeric(TRUE)
)发现)


PS:是的,没有数据表也可以这样做(只需比较移位矩阵
d
;-)

答案不错,但请充实一下?为什么不
colSums(应用(d,1,diff))
?请注意,只有当差异始终为1或0时,这才有效…好吧,我将其应用于我的数据,有时会得到-1。当使用
diff
时,这意味着什么?您介意解释一下该函数的作用吗?从我使用的
循环的
数量可以看出,我对R非常陌生。我将添加一个文本e几分钟:-)很好的解释!谢谢!:)
# Your original data
a=c(rep(0,5),rep(1,5),rep(2,5))
b=c(rep(1,5),rep(1,5),rep(2,5))
d=rbind(a,b)

# Solution starts here...
library(data.table)
dt <- as.data.table(d)  # convert to data.table for high performance. "Performance penalty" here is that the matrix is copied completely (setDT does not work on a matrix)
cols <- ncol(dt)
diff <- dt[, 1:(cols-1), with=FALSE ] != dt[, 2:cols, with=FALSE ]  # find differences (TRUE/FALSE table as result)
rowSums(diff)       # sum the differences per row
[1] 2 1
> diff
        V1    V2    V3    V4    V5    V6    V7    V8    V9  V10   V11   V12   V13   V14
[1,] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
[2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE