我有一个看起来像这样的矩阵:
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,每行有一些开关。 但是,我的数据有数千行和数千列,这个脚本花费的时间太长,无法计算更改。
答案 0 :(得分:6)
使用函数diff
rowSums(t(apply(d,1,diff)))
或Ben的建议(不确定我为什么决定,t
和rowSums
)
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
; - )