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

时间:2016-02-24 15:59:47

标签: 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     2     2
b    1    1    1    1    1    1    1    1    1     1     2     2     2     2     2

我想要做的是计算一行中值的变化次数。例如,在第一行,第5列到第6列以及第10列到第11列有2个更改。

我使用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,每行有一些开关。 但是,我的数据有数千行和数千列,这个脚本花费的时间太长,无法计算更改。

3 个答案:

答案 0 :(得分:6)

使用函数diff

rowSums(t(apply(d,1,diff)))

或Ben的建议(不确定我为什么决定,trowSums

colSums(apply(d,1,diff))

再一次,我假设了&#34; 1&#34;从例子。但如果数字跳跃,你可以尝试

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

答案 1 :(得分:6)

你也可以试试这个:

RecyclerView

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

因此我们将匿名函数apply应用于每一行,该行暂时存储在length(rle(x)$values)中。根据{{​​1}},x函数执行以下操作:

  

计算向量

中相等值运行的长度和值

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

希望这有帮助。

答案 2 :(得分:2)

只是为了一个有趣的解决方案 data.table 可以在数据量巨大的情况下提供更好的性能 - 尽管我不这么认为这种情况):

# 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

工作原理:

我只是通过将列“移”一列来比较两个表,这会导致一个表为TRUE / FALSE值,其中每个TRUE表示与下一列相比值的变化:

> 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; - )