3

IDごとの行の最大の寄与を計算するために、IDが数値の場合に機能する美しいスクリプトがあります。しかし、今日、IDに文字を含めることも可能であることがわかりました(たとえば、ABC10101)。関数が機能するために、データセットは行列に変換されます。ただしdata.matrix(df)、文字はサポートしていません。関数がすべての種類のID(文字、数値など)で機能するように、コードを変更できますか?現在、ID =文字の場合にIDを数値に変換する簡単な回避策を作成しましたが、大きなデータセットの場合はプロセスが遅くなります。

コードの例(関数:貢献度が最も高い最初のエントリを抽出するため、2つのエントリが同じ貢献度を持っている場合は、最初のエントリを選択します):

注:この例では、IDは因子として解釈され、data.matrix()はそれを数値に変換します。以下のコードでは、ID列のタイプは文字であり、出力は下部に示されているとおりである必要があります。注文IDは同じままである必要があります。

tc <- textConnection('
    ID   contribution   uniqID      
   ABCUD022221       40           101  
   ABCUD022221       40           102 
   ABCUD022222       20           103
   ABCUD022222       10           104
   ABCUD022222       90           105
   ABCUD022223       75           106
   ABCUD022223       15           107
   ABCUD022223       10           108        ')

df <- read.table(tc,header=TRUE)

#Function that needs to be altered
uniqueMaxContr <- function(m, ID = 1, contribution = 2) {
  t(
    vapply(
           split(1:nrow(m), m[,ID]), 
           function(i, x, contribution) x[i, , drop=FALSE]
           [which.max(x[i,contribution]),], m[1,], x=m, contribution=contribution
          )
  )
}

df<-data.matrix(df) #only works when ID is numeric
highestdf<-uniqueMaxContr(df)
highestdf<-as.data.frame(highestdf)

この場合、結果は次のようになります。

    ID   contribution   uniqID      
   ABCUD022221       40           101  
   ABCUD022222       90           105
   ABCUD022223       75           106
4

1 に答える 1

7

他の人はそれをより簡潔にすることができるかもしれませんが、これはdata.tableソリューションでの私の試みです:

tc <- textConnection('
    ID   contribution   uniqID      
   ABCUD022221       40           101  
   ABCUD022221       40           102 
   ABCUD022222       20           103
   ABCUD022222       10           104
   ABCUD022222       90           105
   ABCUD022223       75           106
   ABCUD022223       15           107
   ABCUD022223       10           108        ')

df <- read.table(tc,header=TRUE)

library(data.table)
dt <- as.data.table(df)
setkey(dt,uniqID)

dt2 <- dt[,list(contribution=max(contribution)),by=ID]

setkeyv(dt2,c("ID","contribution"))
setkeyv(dt,c("ID","contribution"))

dt[dt2,mult="first"]

##               ID contribution uniqID
## [1,] ABCUD022221           40    101
## [2,] ABCUD022222           90    105
## [3,] ABCUD022223           75    106

編集-より簡潔なソリューション

  • .SDグループ化にdata.tableのサブセットであるを使用してから、を使用しwhich.maxて単一の行を抽出できます。

一行で

dt[,.SD[which.max(contribution)],by=ID]

##               ID contribution uniqID
## [1,] ABCUD022221           40    101
## [2,] ABCUD022222           90    105
## [3,] ABCUD022223           75    106
于 2012-09-10T09:52:00.857 に答える