多くの列を持つフレームがありますc1c2c3 c4 ... c30 d
c1..30で一意のすべての行を集計して検索し、その行のmin(d)を取得します。SQLでは、これはc1、...、c30によるグループになります。
dは日付タイプです。
私はここでいくつかの解決策をスタックで見つけましたが、1)非常に多くの列2)合計の代わりに分を実行するために機能するものはないようです。
どんな入力でも素晴らしいでしょう。
多くの列を持つフレームがありますc1c2c3 c4 ... c30 d
c1..30で一意のすべての行を集計して検索し、その行のmin(d)を取得します。SQLでは、これはc1、...、c30によるグループになります。
dは日付タイプです。
私はここでいくつかの解決策をスタックで見つけましたが、1)非常に多くの列2)合計の代わりに分を実行するために機能するものはないようです。
どんな入力でも素晴らしいでしょう。
data.table
いくつかの偽のデータを含むパッケージを使用した回答は次のとおりです。
library(data.table)
DT<-data.table(matrix(sample(1:2,3000,replace=TRUE),ncol=30))
DT2<-DT[sample(seq_len(nrow(DT)),9000,replace=TRUE)]
# EDIT: now "d" is a date.
DT2[,d:=as.POSIXct(origin = "1960-01-01",rnorm(nrow(DT2), sd = 1000))]
setnames(DT2,c(paste0("c",1:30),"d"))
## pick up herewith your own data, starting with the commented next line
# DT2 <- as.data.table(dataset)
setkeyv(DT2,paste0("c",1:30))
DT3<-DT2[,list(minD=min(d)),by=key(DT2)]
dim(DT2)
# [1] 9000 31
dim(DT3)
# [1] 100 31
マシューからの小さな追加:
+10、そして素敵な偽データ。最初にキーを設定して実行by=key(DT)
できるようにするのは、少し面倒な場合があるため、通常は、簡単にするためにこのようなことをアドホックに行います。しかし、最初に最も自然なことを試してみてください:
DT2[,min(d),by=paste0("c",1:30)]
Error in `[.data.table`(DT2, , min(d), by = paste0("c", 1:30)) :
'by' appears to evaluate to column names but isn't c() or key(). Use by=
list(...) if you can. Otherwise, by=eval(paste0("c", 1:30)) should work.
This is for efficiency so data.table can detect which columns are needed.
エラーメッセージは、代わりに何をする必要があるかを示しています:
ans = DT2[,min(d),by=eval(paste0("c",1:30))]
dim(ans)
[1] 100 31
もちろん、次の自然な考えは次のとおりです。まあ、data.table がby
列名を知っていて、それをエラー メッセージに入れるのに十分賢いなら、なぜそれができないのでしょうか? 答えは、データに基づいて推測しているだけだということです。いくつかのエッジケースでは、それほど明確ではありません。したがって、現在、ユーザーから追加のインテントが必要です: でラッピングしeval
ます。とはいえ、完全に満足しているわけではないので、改善できるかもしれません。
編集: 新しい data.table の名前を変更する
私のアプローチでは、次のminD
ように入力して作成したときに新しい列に名前を付けました
DT3<-DT2[,list(minD=min(d)),by=key(DT2)]
Matthew Dowle のアプローチを使用すると、次のように入力して、ほぼ同じ方法でこれを実現できます。
ans = DT2[,list(minD=min(d)),by=eval(paste0("c",1:30))]
すでに列を作成していて名前を変更したい場合は、次のように使用setnames
します。
setnames(DT3,old="minD",new="theNewMinD")
これにより、全体のコピーが回避data.table
され、メモリの割り当てが保存されます (これらの利点は両方とも、 を使用すると失われnames(DT3)<-"something"
ます)。?setnames
最小限の再現可能な例なしでテストされていません:
apply(unique(dataset), 1, min)
それを分解してください:
x <- unique(dataset) #finds only unique rows
apply(x, 1, min) # applies min across rows
# replace the 1 with a 2 and it applies across columns