2015-12-27 6 views
9

条件が満たされた場合valueNAに置き換えるのにdplyrを使用していますが、そうでないはずの場所にNAを入れています。dplyrの値が条件で満たされないのはなぜですか?

dput:

df <- structure(list(id = c("USC00231275", "USC00231275", "USC00231275", 
"USC00231275", "USC00231275", "USC00231275", "USC00231275", "USC00231275", 
"USC00231275", "USC00231275"), element = c("TMAX", "TMIN", "TMAX", 
"TMIN", "TMAX", "TMIN", "TMAX", "TMIN", "TMAX", "TMIN"), year = c(1937, 
1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937), month = c(5, 
5, 5, 5, 5, 5, 5, 5, 5, 5), day = c(1, 1, 2, 2, 3, 3, 4, 4, 5, 
5), date = structure(c(-11933, -11933, -11932, -11932, -11931, 
-11931, -11930, -11930, -11929, -11929), class = "Date"), value = c(0, 
53.96, 68, 44.96, 62.06, 53.96, 73.04, 53.96, 69.08, 50)), .Names = c("id", 
"element", "year", "month", "day", "date", "value"), row.names = c(NA, 
10L), class = "data.frame") 

data.frameは(注:条件は、行1に会い、2れる)

  id element year month day  date value 
1 USC00231275 TMAX 1937  5 1 1937-05-01 0.00 
2 USC00231275 TMIN 1937  5 1 1937-05-01 53.96 
3 USC00231275 TMAX 1937  5 2 1937-05-02 68.00 
4 USC00231275 TMIN 1937  5 2 1937-05-02 44.96 
5 USC00231275 TMAX 1937  5 3 1937-05-03 62.06 
6 USC00231275 TMIN 1937  5 3 1937-05-03 53.96 
7 USC00231275 TMAX 1937  5 4 1937-05-04 73.04 
8 USC00231275 TMIN 1937  5 4 1937-05-04 53.96 
9 USC00231275 TMAX 1937  5 5 1937-05-05 69.08 
10 USC00231275 TMIN 1937  5 5 1937-05-05 50.00 

dplyr

df %>% 
    group_by(date) %>% 
    mutate(
    value = if(value[element == 'TMIN'] >= value[element == 'TMAX']) 
     as.numeric(NA) else value 
) 

      id element year month day  date value 
     (chr) (chr) (dbl) (dbl) (dbl)  (date) (dbl) 
1 USC00231275 TMAX 1937  5  1 1937-05-01 NA 
2 USC00231275 TMIN 1937  5  1 1937-05-01 NA 
3 USC00231275 TMAX 1937  5  2 1937-05-02 68.00 
4 USC00231275 TMIN 1937  5  2 1937-05-02 44.96 
5 USC00231275 TMAX 1937  5  3 1937-05-03 NA 
6 USC00231275 TMIN 1937  5  3 1937-05-03 NA 
7 USC00231275 TMAX 1937  5  4 1937-05-04 73.04 
8 USC00231275 TMIN 1937  5  4 1937-05-04 53.96 
9 USC00231275 TMAX 1937  5  5 1937-05-05 69.08 
10 USC00231275 TMIN 1937  5  5 1937-05-05 50.00 

注意変更する必要行のみその12ですが、dplyrは、条件が満たされていなくても、56の行を変更しました。

+0

うわー、私は少しのためにこれを見つめ、この試してください: 'Z <- df %>%のGROUP_BY(年、月、日を)%>%(テスト=差分を変異させます(値>%)) 'これはうまくいきますが、グループ解除を解除すると突然NAが戻ってしまいます...(%)%ungroup%>%mutate(value2 = ifelse(test> 0、NA、as.numeric(value)))私は幾分謎にされています – Shape

+0

@Shapeはい、これはあなたの以前の答えからのもので、元のデータセットでは動作しません。非常に奇妙な私は思った。ありがとう! – Vedda

+1

これは明らかにNAを置換値として使用することで問題になります。これを見てみましょう: 'df%>%group_by(年、月、日)%>%mutate(値= if(値[要素== 'TMIN'] > = value [要素== 'TMAX'])1 else value) 'これは動作します。しかし、NAは問題を引き起こしています。これはバグのように聞こえます。 – Shape

答えて

1

次のコードは、あなたが、これはバグであるかどうかの問題について

df %>% 
    group_by(date) %>% 
    mutate(new_value = ifelse(((value[element == 'TMIN'] >= value[element == 'TMAX']) & element=='TMIN'), NA, value)) %>% 
    ungroup 

をやろうとしている何をすべき、私はそれがあるとは思いません。 res列に見られるようにTMIN> = TMAX一年間のデータだけを見ると、あなたが

df %>% 
    filter(date == '1937-05-01') %>% 
    mutate(res = (value[element == 'TMIN'] >= value[element == 'TMAX'])) %>% 
    mutate(new_value = ifelse((res & element=='TMIN'), NA, value)) 

      id element year month day  date value res new_value 
1 USC00231275 TMAX 1937  5 1 1937-05-01 0.00 TRUE   0 
2 USC00231275 TMIN 1937  5 1 1937-05-01 53.96 TRUE  NA 

を以下している構造value[element == 'TMIN'] >= value[element == 'TMAX'])は常にtrueになります。以下のコードは、これを少し分けて、うまくいけば明確にする(私が望む)。

### Just looking at one date 
> df2 <- df %>% filter(date == '1937-05-01') 
> df2 
      id element year month day  date value 
1 USC00231275 TMAX 1937  5 1 1937-05-01 0.00 
2 USC00231275 TMIN 1937  5 1 1937-05-01 53.96 

### This comparison will be recycled for every element in the group, 
### so it will always be TRUE or always FALSE. 
> c(df2$value[df2$element == 'TMIN'], df2$value[df2$element == 'TMAX']) 
[1] 53.96 0.00 

グループ全体で1つの比較が存在するため、常にTRUEまたは常にFALSEと表示されます。

正しい結果を返すコードは、比較がどのように行われるかを示しています。

一つの可能​​な最終的な解決策は次のようになります。

df %>% 
    group_by(date) %>% 
    mutate(value = ifelse(((value[element == 'TMIN'] >= value[element == 'TMAX']) & element=='TMIN'), NA, value)) %>% 
    ungroup 
+0

ifelseがこれを回避することができると私は同意しますが、TRUEまたはFALSEの1つは元のコードの意図です。これは、ベクトル化された複数の比較ではなく、2回のルックアップに基づいて、各グループに対して1回の操作を実行した結果です。 (これは特に、長いデータに 'a'や 'b'よりも多くの要素があるが、それでもすべてのグループデータを含める場合に当てはまります)。 TRUE/FALSEが1つ返されると、通常は値が乗算されます。これは、NAが他の値と同様に行うべきことです。 – Shape

関連する問題