5

Rのdata.table(またはdata.frame)の場合、同じキーを持つ行の別の値からの距離「距離」が指定された列「value」の値を含むすべての行を検索したいと思います。したがって、次のようになります。

distance <- 22
   key value
   A     1
   B     1
   C     1
   D     1
   A     4
   B     4
   A    23
   B    23
   B    26
   B    26
   C    30

元のテーブルに、同じキーで存在する行数のカウントと、そこから+22の値で注釈を付けたいと思います。

  key value count
  A     1     1
  B     1     1
  C     1     0
  D     1     0
  A     4     0
  B     4     2
  A    23     0
  B    23     0
  B    26     0
  B    26     0
  C    30     0

Rでデータを操作するためのこの自己参照アプローチをどこから始めればよいのか、私にはよくわかりません。最初の試みでは、2番目のテーブルを作成し、それと照合しようとしましたが、それは奇妙で貧弱なアプローチのようでした。

注:私はdata.tableパッケージを使用していますが、この場合、作業が簡単になる場合はdata.frameから作業できます。

再現性:

require(data.table)
source <- data.table(data.frame(key=c("A","B","C","D","A","B","A","B","B","B", "C"),value=c(1,1,1,1,4,4,23,23,26,26,30)))
result <- data.table(data.frame(key=c("A","B","C","D","A","B","A","B","B","B","C"),value=c(1,1,1,1,4,4,23,23,26,26,30),count=c(1,1,0,0,0,2,0,0,0,0,0)))
4

2 に答える 2

5

これがdata.tableベースのソリューションです。(もしあれば)それに対してどのような改善を行うことができるかを知りたいと思います。

# Your code
library(data.table)
source <- 
data.table(data.frame(key = c("A","B","C","D","A","B","A","B","B","B", "C"),
                      value = c(1,1,1,1,4,4,23,23,26,26,30)))

その奇妙なのdata.table(data.frame(...data.table()、という引数keyもあるからです。data.tableこれは、という列を持つを作成する1つの方法"key"です。引数名の競合を回避するために大文字にすることは、より標準的な構文を示しています。

source <- data.table(Key = c("A","B","C","D","A","B","A","B","B","B","C"),
                     Value = c(1,1,1,1,4,4,23,23,26,26,30))

次に、as.integer()後で必要にならないように、Value列のタイプをnumericからinteger現在に変更します。Rにあるよりも1、それはです。通常、データをとしてではなく、として保存する方が効率的です。次の行は、上記のsをたくさん入力するよりも簡単です。numeric1LintegerintegerintegerintegernumericL

source[,Value:=as.integer(Value)]   # change type from `numeric` to `integer`

次に進みます

distance <- 22L
setkey(source, Key, Value)

# Heart of the solution (following a few explanatory comments):
#  "J()"   : shorthand for 'data.table()'
#  ".N"    : returns the number of rows that matched a line (see ?data.table)
#  "[[3]]" : as with simple data.frames, extracts the vector in column 3

source[,count:=source[J(Key,Value+distance),.N][[3]]]
source
      key value count
 [1,]   A     1     1
 [2,]   A     4     0
 [3,]   A    23     0
 [4,]   B     1     1
 [5,]   B     4     2
 [6,]   B    23     0
 [7,]   B    26     0
 [8,]   B    26     0
 [9,]   C     1     0
[10,]   C    30     0
[11,]   D     1     0

参照により直接:=変更されていることに注意してください。それだけです。sourceただしsetkey()、元のデータの順序も変更しました。元の注文を保持する必要がある場合は、次のようにします。

source <- data.table(Key = c("A","B","C","D","A","B","A","B","B","B","C"),
                     Value = c(1,1,1,1,4,4,23,23,26,26,30))
source[,Value:=as.integer(Value)]   
source[,count:=setkey(copy(source))[source[,list(Key,Value+distance)],.N][[3]]]

      Key Value count
 [1,]   A     1     1
 [2,]   B     1     1
 [3,]   C     1     0
 [4,]   D     1     0
 [5,]   A     4     0
 [6,]   B     4     2
 [7,]   A    23     0
 [8,]   B    23     0
 [9,]   B    26     0
[10,]   B    26     0
[11,]   C    30     0
于 2012-05-23T19:29:20.883 に答える
1

mapplyキーと値のすべての組み合わせをループするために使用できます。

data.table(t(mapply(function(key,val) 
      c(key=key,value=val,count=length(source$value[source$key==key & source$value>(val+distance)]) )
   , as.character(source$key),source$value)))
于 2012-05-23T18:31:09.503 に答える