2017-04-20 5 views
0

(私は答えが得られた後、私は本当に馬鹿だと感じていますが、私はこれを理解できませんでした)Rでは、data.frameの特定のサブセットに対して操作を実行する方法は?

私は最後に空の列を持つdata.frameを持っています。ほとんどの場合、NAsで埋め尽くされますが、その行に値を設定したいと考えています。この列は、data.frameの列の1つに欠落しているデータの推測を表します。 2つの行のがMaxPlayersのために、 "N/A" を持っていることを

Game | Rating | MinPlayers | MaxPlayers | MaxPlayersGuess 
--------------------------------------------------------- 
A | 6  | 3   | 6   | 
B | 7  | 3   | 7   | 
C | 6.5 | 3   | N/A  |median(df$MaxPlayers[df$MinPlayers ==3,]) 
D | 7  | 3   | 6   | 
E | 7  | 3   | 5   | 
F | 9.5 | 2   | 5   | 
G | 6  | 2   | 4   | 
H | 7  | 2   | 4   | 
I | 6.5 | 2   | N/A  |median(df$MaxPlayers[df$MinPlayers ==2,]) 
J | 7  | 2   | 2   | 
K | 7  | 2   | 4   | 

お知らせ:

私の最初のdata.frameは次のようになります。私がしようとしていることは、MaxPlayersとは何かを推測するために必要な情報を使用することです。 3人のゲームのメディアン(MaxPlayers)が6の場合、MaxPlayerGuessはMinPlayers == 3、MaxPlayers == N/Aのゲームで6になります。 (私は、上の例で取得する必要がありますどのような値MaxPlayerGuessコードで示すことを試みてきた。)

結果data.frameは次のようになります。

Game | Rating | MinPlayers | MaxPlayers | MaxPlayersGuess 
--------------------------------------------------------- 
A | 6  | 3   | 6   | 
B | 7  | 3   | 7   | 
C | 6.5 | 3   | N/A  |6 
D | 7  | 3   | 6   | 
E | 7  | 3   | 5   | 
F | 9.5 | 2   | 5   | 
G | 6  | 2   | 4   | 
H | 7  | 2   | 4   | 
I | 6.5 | 2   | N/A  |4 
J | 7  | 2   | 2   | 
K | 7  | 2   | 4   | 

は1つの試みの結果を共有するには:

gld$MaxPlayersGuess <- ifelse(is.na(gld$MaxPlayers), median(gld$MaxPlayers[gld$MinPlayers,]), NA) 


Error in gld$MaxPlayers[gld$MinPlayers, ] : 
incorrect number of dimensions 

答えて

2

投稿された例との相対的な更新。

これは今日の私のヒントです。必要なときに必要なものを計算し、これらの論理的な連続性をすべて使用するのではなく、それを取得する方が簡単な場合もあります。一度にすべてを計算する方法を考え出しています。それは混乱させてしまい、ステップに分けてしまいます。 "MinPlayer"の可能なグループごとに "MaxPlayer"の中央値を知る必要があります。 MaxPlayerが見つからない場合は、その値を使用します。だから、これを行う簡単な方法があります。

#generate fake data 
MinPlayer <- rep(3:2, each = 4) 
MaxPlayer <- rep(2:5, each = 2, times = 2) 

df <- data.frame(MinPlayer, MaxPlayer) 

#replace some values of MaxPlayer with NA 
df$MaxPlayer <- ifelse(df$MaxPlayer == 3, NA, df$MaxPlayer) 

####STARTING DATA 
# > df 
# MinPlayer MaxPlayer 
# 1   3   2 
# 2   3   2 
# 3   3  NA 
# 4   3  NA 
# 5   2   4 
# 6   2   4 
# 7   2   5 
# 8   2   5 
# 9   3   2 
# 10   3   2 
# 11   3  NA 
# 12   3  NA 
# 13   2   4 
# 14   2   4 
# 15   2   5 
# 16   2   5 

####STEP 1 
#find the median of MaxPlayer for each group of MinPlayer (e.g., when MinPlayer == 1, 2 or whatever) 
#just add a column to the data frame that has the right median value for each subset of MinPlayer in it and grab that value to use later. 
library(plyr) #plyr is a great way to compute things across data subsets 
df <- ddply(df, c("MinPlayer"), transform, 
      median.minp = median(MaxPlayer, na.rm = TRUE)) #ignore NAs in the median 

####STEP 2 
#anytime that MaxPlayer == NA, grab the median value to replace the NA, otherwise keep the MaxPlayer value 
df$MaxPlayer <- ifelse(is.na(df$MaxPlayer), df$median.minp, df$MaxPlayer) 

####STEP 3 
#you had to compute an extra column you don't really want, so drop it now that you're done with it 
df <- df[ , !(names(df) %in% "median.minp")] 

####RESULT 
# > df 
# MinPlayer MaxPlayer 
# 1   2   4 
# 2   2   4 
# 3   2   5 
# 4   2   5 
# 5   2   4 
# 6   2   4 
# 7   2   5 
# 8   2   5 
# 9   3   2 
# 10   3   2 
# 11   3   2 
# 12   3   2 
# 13   3   2 
# 14   3   2 
# 15   3   2 
# 16   3   2 

ここで、以下の旧答え....

再現性の例を投稿してください!

#fake data 
this <- rep(1:2, each = 1, times = 2) 
that <- rep(3:2, each = 1, times = 2) 

df <- data.frame(this, that) 

あなただけの何かが条件を満たしている値を見つけ、...基本的なインデックスについて例えば求めている場合は、この条件に合致する値の行インデックスを返します(ルックアップする?):

> which(df$this < df$that) 
[1] 1 3 

これは、行インデックスではなく、条件に一致するもののVALUEを返します。データフレームの正しい列(ここでは「this」)で対応する値を見つけるには、

> df[which(df$this < df$that), "this"] 
[1] 1 1 

"this"が "less"の場合に計算を適用し、データフレームに新しい列を追加するには、 "ifelse"を使用します。 elseが論理的なベクトルを作成し、その論理的なベクトルがあなたの条件にマッチした場合、あなたの条件に合ったもの(例:あなたの論理的なテスト== TRUE)になります。

#if "this" is < "that", multiply by 2 
df$result <- ifelse(df$this < df$that, df$this * 2, NA) 

> df 
this that result 
1 1 3  2 
2 2 2  NA 
3 1 3  2 
4 2 2  NA 

再現可能な例がなければ、これ以上提供することはできません。

+0

謝罪、私も、私が再現可能な例を提供する方法がわからない手順をコーディングを開始する方法がわからないので。 – Zelbinian

+0

お返事ありがとうございます。いくつかの提案を試してみることで、問題をよりよく理解し、例を投稿する方法を見つけ出すことができました。 – Zelbinian

+0

@ Zelbinianだから、一般的にgriffmerの答えは – Chris

0

あなたはすでに@ griffmerの答えで必要なものはすべて持っていると思います。しかし、あまりエレガント多分より直感的な方法は、ループのようになります。

## Your data: 
df <- data.frame(
     Game = LETTERS[1:11], 
     Rating = c(6,7,6.5,7,7,9.5,6,7,6.5,7,7), 
     MinPlayers = c(rep(3,5), rep(2,6)), 
     MaxPlayers = c(6,7,NA,6,5,5,4,4,NA,2,4)  
) 

## Loop over rows: 
df$MaxPlayersGuess <- vapply(1:nrow(df), function(ii){ 
      if (is.na(df$MaxPlayers[ii])){ 
       median(df$MaxPlayers[df$MinPlayers == df$MinPlayers[ii]], 
         na.rm = TRUE)    
      } else { 
       df$MaxPlayers[ii] 
      }   
     }, numeric(1)) 

あなたがdplyrを使用する場合は、あなたに

df 
# Game Rating MinPlayers MaxPlayers MaxPlayersGuess 
# 1  A 6.0   3   6    6 
# 2  B 7.0   3   7    7 
# 3  C 6.5   3   NA    6 
# 4  D 7.0   3   6    6 
# 5  E 7.0   3   5    5 
# 6  F 9.5   2   5    5 
# 7  G 6.0   2   4    4 
# 8  H 7.0   2   4    4 
# 9  I 6.5   2   NA    4 
# 10 J 7.0   2   2    2 
# 11 K 7.0   2   4    4 
0

を与え、あなたは試すことができます:

入力:

df <- data.frame(
    Game = LETTERS[1:11], 
    Rating = c(6,7,6.5,7,7,9.5,6,7,6.5,7,7), 
    MinPlayers = c(rep(3,5), rep(2,6)), 
    MaxPlayers = c(6,7,NA,6,5,5,4,4,NA,2,4)  
) 

プロセス:

df %>% 
    group_by(MinPlayers) %>% 
    mutate(MaxPlayers = if_else(is.na(MaxPlayers), median(MaxPlayers, na.rm=TRUE), MaxPlayers)) 

これは、データベースをグループ化してMinPlayersとし、欠損データがある行にMaxPlayersの中央値を割り当てます。

出力:

Source: local data frame [11 x 4] 
Groups: MinPlayers [2] 

    Game Rating MinPlayers MaxPlayers 
    <fctr> <dbl>  <dbl>  <dbl> 
1  A 6.0   3   6 
2  B 7.0   3   7 
3  C 6.5   3   6 
4  D 7.0   3   6 
5  E 7.0   3   5 
6  F 9.5   2   5 
7  G 6.0   2   4 
8  H 7.0   2   4 
9  I 6.5   2   4 
10  J 7.0   2   2 
11  K 7.0   2   4 
関連する問題