R 创建指示器

R 创建指示器,r,matrix,indicator,R,Matrix,Indicator,我想为矩阵创建一个数字指示器,这样对于一个变量中的每个唯一元素,它会基于另一个变量中的元素创建一个长度序列。例如: frame<- data.frame(x = c("a", "a", "a", "b", "b"), y = c(3,3,3,2,2)) frame x y 1 a 3 2 a 3 3 a 3 4 b 2 5 b 2 非常感谢您的帮助。谢谢。您可以在x上拆分数据.frame,并基于此生成一个新的id列: > frame$z <- unlist(lapply(

我想为矩阵创建一个数字指示器,这样对于一个变量中的每个唯一元素,它会基于另一个变量中的元素创建一个长度序列。例如:

frame<- data.frame(x = c("a", "a", "a", "b", "b"), y = c(3,3,3,2,2))
frame
  x y
1 a 3
2 a 3
3 a 3
4 b 2
5 b 2

非常感谢您的帮助。谢谢。

您可以在
x
上拆分
数据.frame
,并基于此生成一个新的id列:

> frame$z <- unlist(lapply(split(frame, frame$x), function(x) 1:nrow(x)))
> frame
  x y z
1 a 3 1
2 a 3 2
3 a 3 3
4 b 2 1
5 b 2 2
另一种方法:

frame$z <- unlist(lapply(rle(as.numeric(frame[, "x"]))$lengths, seq_len))
frame$zNo
ave

frame$z <- with(frame, ave(y,x,FUN=seq_along) )
frame

#  x y z
#1 a 3 1
#2 a 3 2
#3 a 3 3
#4 b 2 1
#5 b 2 2
我最初的想法是使用:

frame[,z := .SD[,.I], by=x]

其中
.SD
数据的每个子集。表
x
拆分
.I
返回整个
数据表的行号。因此,
.SD[,.I]
返回每个组中的行号。尽管如此,正如@mnel所指出的,与其他方法相比,这是低效的,因为每个组都需要将整个
.SD
加载到内存中才能运行此计算。

尝试此方法,其中
x
是要进行分组的列,
y
是任何数字列。如果没有数字列,则使用沿(x)的
seq_
,例如,代替
y

transform(frame, z = ave(y, x, FUN = seq_along))

这是x的指示器,y的指示器还是两者都有?打得好,长官,打得好+1@TylerRinker,没那么好。。另外两个解决方案要求数据由
x
排序,这一个比您更快…:-)是的,我还感到惊讶的是,即使在几分钟之后,也没有人建议使用
ave
。您可以使用
1:nrow(.SD)
data.table(frame)[,z:=sequence(.N),by=x]
)引用
.SD
将整个
.SD
加载到内存中。使用
z:=seq_len(.N)
序列(rle(as.numeric(frame$x))$length)
对我来说似乎更直接。
rle
方法的一个可能问题(或优点,取决于OP想要什么)是,数据需要先排序,否则每次“x”中的值发生变化时,序列都会被重置。@阿南达我假设OP确实想要这样做,但可能不是这样。不要做
.SD[,.I]
,使用
z:=seq\u len(.N)
。对于
.SD
较大的情况,后者将具有更高的内存(和时间)效率。
[,.I]
仅适用于
.SD
而不是任意的列集。我怀疑
.SD
魔力背后存在某种合并。@Scottrichie原因
.SD[,.I]
之所以有效,是因为在此
中.I
的范围在
.SD
中,例如,请参见
框架[,c('z1','z2'):=list(.I,.SD[,.I]),by=x]
frame$z <- with(frame, ave(y,x,FUN=seq_along) )
frame

#  x y z
#1 a 3 1
#2 a 3 2
#3 a 3 3
#4 b 2 1
#5 b 2 2
#library(data.table)
#frame <- as.data.table(frame)
frame[,z := seq_len(.N), by=x]
frame[,z := .SD[,.I], by=x]
transform(frame, z = ave(y, x, FUN = seq_along))