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