8

R データ フレームがあります。

a <- 1:12  
list <- c(rep("x",3),rep("y",4),rep("z",3),rep("x",2))  
data <- data.frame(a,list)

data  
 a list  
 1    x  
 2    x  
 3    x  
 4    y  
 5    y  
 6    y  
 7    y  
 8    z  
 9    z  
10    z  
11    x  
12    x

「リスト」の値が変更されるたびに 1 からカウントを開始する新しい列を作成します。つまり、この例では次のようになります。

b <- c(1:3,1:4,1:3,1:2)    
data <- data.frame(a,list,b)  

私は R の専門家には程遠いので、これを行う効率的な方法を一生考え出すことはできません。私の主な問題は、「リスト」の任意の値がいつでも戻ってくる可能性があることですが、1 つの値のブロックの長さには規則がありません。誰にもアイデアはありますか?ありがとう!

4

2 に答える 2

6

rle()のランレングスを取得するために使用listし、便利な関数を使用して、によって返されsequence()たコンポーネントから目的のカウンターを生成します。$lengthsrle()

R> sequence(rle(as.character(data$list))$lengths)
 [1] 1 2 3 1 2 3 4 1 2 3 1 2

listでは係数が許可されていないため、原子ベクトル (私の場合は文字ベクトル)に変換する必要があることに注意してくださいrle()

それを に入れるにはdata、これを次のような呼び出しでラップします

data <- transform(data, b = sequence(rle(as.character(list))$lengths))

を与える

R> data <- transform(data, b = sequence(rle(as.character(list))$lengths))
R> data
    a list b
1   1    x 1
2   2    x 2
3   3    x 3
4   4    y 1
5   5    y 2
6   6    y 3
7   7    y 4
8   8    z 1
9   9    z 2
10 10    z 3
11 11    x 1
12 12    x 2
于 2012-10-29T09:44:06.347 に答える
5

重要なアイデアは、rle()(ランレングス エンコーディング)を使用することです (data$listアトミック ベクトルに強制した後 - 結局のところ、特定のエントリには関心がありません)。次に、 を使用seq()して、1 から始まり、計算されたランの長さで終わるシーケンスを作成します。最後に、これらすべてのシーケンスを一緒に貼り付けます。

unlist(lapply(rle(as.numeric(data$list))$lengths,FUN=seq,from=1))
于 2012-10-29T09:41:24.043 に答える