该rle
函数返回一个列表,但这并不是很明显,因为当您键入对象的名称时,可以让 R 打印您想要的任何内容,并且作者rle
已使其打印其他内容。为了找出对象的结构,您可以使用str
,例如
x <- c(1, 1, 1, 2, 2, 5, 5, 5, 5, 1)
codes <- rle(x)
str(codes)
codes$lengths
您可以通过键入相应的值来获取长度。
无论如何,尽管有统计问题,这里是如何做你想做的事。假设你有 30 个科目,他们回答了 8 个问题。您的数据可能如下所示
set.seed(123)
repsonses <- data.frame(matrix(sample(0:5, 8*30, replace=T), nc=8))
> head(responses)
X1 X2 X3 X4 X5 X6 X7 X8
1 3 2 4 2 4 1 1 5
2 1 5 2 1 5 3 1 1
3 1 3 1 2 3 5 5 3
4 4 4 5 3 4 2 4 2
5 5 5 2 5 3 1 2 4
6 3 3 3 3 1 1 3 2
您可以像这样提取每个主题的最大运行长度:
> max.lengths <- apply(responses, 1, function(x) max(rle(x)$lengths))
> max.lengths
[1] 2 2 2 2 2 4 3 1 1 2 2 1 2 3 2 1 2 2 1 2 1 2 1 2 2 2 2 2 2 1
前 5 个科目的最大长度为 2,第六个科目的最大长度为 4,所以看起来是正确的。
同样对于平均长度
> mean.lengths <- apply(responses, 1, function(x) mean(rle(x)$lengths))
> head(mean.lengths)
[1] 1.142857 1.142857 1.142857 1.142857 1.142857 2.000000
例如,第一个人的平均长度是 $1,1,1,1,1,2,1$ 的平均值,即 $8/7$,这与 R 所说的一致。
要通过响应分解整个事情,您可以使用相同的想法和这样的tapply
功能:
bd <- function(x){
means <- tapply(x$lengths, factor(x$values,levels=0:5), mean)
means[is.na(means)] <- 0
maxes <- tapply(x$lengths, factor(x$values,levels=0:5), max)
maxes[is.na(maxes)] <- 0
M <- rbind(means, maxes)
rownames(M) <- c("mean", "max")
M
}
lapply(apply(responses, 1, rle), bd)
这会输出另一个列表。例如,如果你向上滚动,你会看到主题 25,它说
[[25]]
0 1 2 3 4 5
mean 0 1 2 1 0 2
max 0 1 2 1 0 2
与之比较
> responses[25,]
X1 X2 X3 X4 X5 X6 X7 X8
25 3 5 5 3 2 2 1 3
所以它给出了正确的答案。您可以为此列表命名,例如
break.downs <- lapply(apply(responses, 1, rle), bd)
然后您可以i
通过键入访问主题条目
break.downs[[i]]
对于 ID 号列的问题,如果包括在内,例如第 1 列,您可以对它进行整个分析responses[ ,-1]
,这应该没问题。$-1$ 只是删除第一列。
PS。抱歉,我刚刚注意到我是用 $0$ 到 $5$ 而不是 $1$ 到 $5$ 来做的,但你只需要在函数中更改levels=0:5
为,它应该也能正常工作。levels=1:5
bd