0

サッカーシーズンのプレーヤーとチームのデータをマージしたデータフレームがあるので、特定のシーズンの特定のプレーヤーについて、次のようなデータがあります。

df <- data.frame(team=c(NA,"CRP",NA,"CRP","CRP",NA),
             player=c(NA,"Ed",NA,"Ed","Ed",NA),
             playerGame= c(NA,1,NA,2,3,NA),
             teamGame =c(1,2,3,4,5,6)) 

NAが、プレーヤーがその特定のチームゲームに出場しなかったことを示している場合

チームとプレーヤーのNAをそれぞれ「CRP」と「Ed」に最も効率的に置き換え、この場合は0、1、1、2、3、3のplGame出力を得るにはどうすればよいでしょうか。


編集

申し訳ありませんが、夜中に目が覚めたときにこれを書いたので、問題を単純化しすぎた可能性があります。これがはるかに大きなデータセットのサブセットであり、プレーヤーとチームのハードコードの直接の置き換えでは不十分であったにもかかわらず、彼/彼女でさえそれをフォローしなかったという事実に気付いたのは1人だけのようです。返信ありがとうございます。動物園パッケージのna.locfに関するDseeのヒントとAKの回答の最初の行は、前進するための最良の方法を提供しているようです。

df$playerGame[df$teamGame == min(df$teamGame) & is.na(df$playerGame) == TRUE] <- 0
na.locf(df$playerGame)

これは、シーケンスを開始するための複数のNAの不測の事態をカバーします。私の場合、min(df $ teamGame)は常に1になるので、ハードコーディングすると速度が上がる可能性があります

より現実的な例はここにあります

library(zoo)
library(plyr)

newdf <- data.frame(team=c("CRP","CRP","CRP","CRP","CRP","CRP","TOT","TOT","TOT"),
             player=c(NA,"Ed",NA,"Bill","Bill",NA,NA,NA,"Tom"),
             playerGame= c(NA,1,NA,1,2,NA,NA,NA,1),
             teamGame =c(1,2,3,1,2,3,1,2,3))

これで、すべての行のチームを表示できます。各チームは、シーズンに3つのゲームをプレイします。エドとビルはCRPでプレーし、それぞれゲーム2と1、2に登場します。トムはゲーム3でのみTOTでプレーします。プレーヤー名は一意であると想定します(実際のデータでも)

別の列「playerTeam」を作成する必要があるようです。

newdf$playerTeam <- 0

for (i in 1:nrow(newdf)) {
newdf$playerTeam[i] <-ceiling(i/3)
}

次に、この値を使用してプレーヤーのギャップを埋めることができます。NAを省略したソート機能を使用しました

newdf <- ddply(newdf,.(playerTeam),transform,player=sort(player)[1])

その後、前述のコードを使用できます

newdf$playerGame[newdf$teamGame == 1 & is.na(newdf$playerGame) == TRUE] <- 0
newdf$playerGame <- na.locf(newdf$playerGame)

   team player playerGame teamGame playerTeam
1  CRP     Ed          0        1          1
2  CRP     Ed          1        2          1
3  CRP     Ed          1        3          1
4  CRP   Bill          1        1          2
5  CRP   Bill          2        2          2
6  CRP   Bill          2        3          2
7  TOT    Tom          0        1          3
8  TOT    Tom          0        2          3
9  TOT    Tom          1        3          3

私もシーズン中に構築する必要がありますが、それは問題ではないはずです

ここに何か足りないものがありますか?

処理する行が数十万行あるので、スピードアップが役立つでしょう。たとえば、ddplyを避けて、data.tableアプローチまたは別の適用関数を使用したいと思うでしょう。

4

3 に答える 3

2

あなたが望むものには2つの部分があるようです:

  1. プレーヤー名とチームを事前に決定された値に置き換えたい
  2. あなたはplayerGameのリストを通してゲームのカウントを繰り越したいと思っています

(1)の場合、次のことができます。

df$team[is.na(df$team)] <- 'CRP' 

同様に、データフレームの他のコンポーネントを変更できます

(2)の場合、これを行うことができます。

if(is.na(df$playerGame[1])) {
    df$playerGame[1] <- 0
}
for(i in 2:length(df$playerGame)) { 
    if(is.na(x[i])) {
        df$playerGame[i] <- df$playerGame[i-1]
    }
} 

次にdf$playerGame

[1] 0 1 1 2 3 3

おそらくこれを行うには非常に気の利いた方法がありますが、これは明らかに読みやすいです...

于 2012-11-22T16:58:09.173 に答える
1

NAを選択するには、たとえばplayer

  df$player[is.na(df$player)]

次に、これらの使用に値を割り当てます

  df$player[is.na(df$player)]  <- "Ed"

プレーヤー列全体に同じ名前を割り当てたい場合は、値を選択する必要はありません。

  df$player[]  <-  "Ed"   # you can omit the brackets [], which are shown just for emphasis

その後、同じことを行うことができますdf$team


ちなみに、データフレームを作成するときに、すでに存在する値以外の値を追加する場合は、追加する必要があります。stringsAsFactors=FALSE

 data.frame( . , stringsAsFactors=FALSE)
于 2012-11-22T14:40:46.720 に答える
1

チームとプレーヤーのNAを置き換えます。

df$team[is.na(df$team)] <- "CRP"
df$player[is.na(df$player)] <- "Ed"

隣接する値を取得するためのより効率的な方法がおそらくありますが、それは機能します。

あなたの例のように、最初または/および最後の値がNAの場合、2つの追加行を使用する必要がありました。

df$playerGame[df$teamGame == min(df$teamGame) & is.na(df$playerGame) == TRUE] <- 0
df$playerGame[df$teamGame == max(df$teamGame) & is.na(df$playerGame) == TRUE] <- max(df$playerGame, na.rm = TRUE)

他のすべての観測値の場合、これは隣接する値を取得します。

df$playerGame[is.na(df$playerGame) == TRUE] <- df$playerGame[-1]

df

team player playerGame teamGame
CRP     Ed          0        1
CRP     Ed          1        2
CRP     Ed          1        3
CRP     Ed          2        4
CRP     Ed          3        5
CRP     Ed          3        6

複数のチームやプレーヤーの場合は、ddply(plyr)と組み合わせることをお勧めします。

于 2012-11-22T15:48:35.963 に答える