2015-12-27 10 views
9

Bir koşul karşılanırsa, ile value'u değiştirmek için dplyr kullanıyorum, ancak olmaması gereken yere NA koyar.Neden dplyr kaldırma değerleri koşullara uygun değil?

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 (Not: durum sadece satır 1 araya ve 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 

Uyarı satırları değişmesi gerektiğini 1 ve 2, ancakKoşullar yerine getirilemese bile 0, 5 ve 6 satırlarını değiştirdi.

+0

Vay be, ben biraz bu baktı, bu deneyin (value))%>% ungroup%>% mutate (value2 = ifelse (test> 0, NA, as.numeric (value))) Bu çalışır, ancak aniden gruba çıkarsanız NA'lar tekrar geri döner ... Ben biraz mystified – Shape

+0

@Shape Evet, bu önceki cevabınızdı ve özgün veri kümesi üzerinde çalışmıyor gibi görünüyor. Çok garip düşündüm. Teşekkürler! – Vedda

+1

görünüşte, NA değerini değiştirme değeriyle kullanmakta olan bir soruna bakın: 'df%>% group_by (yıl, ay, gün)%>% mutate (value = if (value [element == 'TMIN'] > = değer [element == 'TMAX']) 1 başka değer) 'bu çalışır. Ama NA sorunlara neden oluyor, bu bir hata gibi geliyor – Shape

cevap

1

Aşağıdaki kod Bunun bir hata olduğunu ya da değil, öyle olduğunu sanmıyorum olmadığının soru için

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

yapmaya çalıştığımız şeyi yapmalıdır. res sütunda görülebileceği gibi Tmin> = T MAX, sen

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 

yapı value[element == 'TMIN'] >= value[element == 'TMAX']) aşağıdaki nerede bir yıl için sadece verilerine baktığımızda her zaman doğru olacaktır. Aşağıdaki kod, umarım açıklığa kavuşturmak için biraz bozar (umarım).

### 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 

grubun tamamı için bir karşılaştırma olduğundan, her zaman DOĞRU ya da her zaman YANLIŞ göreceksiniz.

Doğru sonucu veren kod, karşılaştırmanın nasıl yapılabileceğini gösterir.

olası bir nihai çözüm olabilir: `z <- df %>% group_by (yıl, ay, gün)%>% mutasyona (test = diff:

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

Bu yüzden, eğer ifelse'nin bunu aşabileceğine katılıyorum, tek DOĞRU veya yanlış orijinal kodun amacıydı. Her grup için, çoklu, vektörel karşılaştırmalar yerine, 2 arama temelinde tek bir işlem yürütme sonucuna sahiptir. (Bu özellikle uzun verilerinizin "a" ve "b" den daha fazla faktörleri varsa, ancak yine de tüm grup verilerini dahil etmek istiyorsanız doğrudur). Tek bir DOĞRU/YANLIŞ döndürüldüğünde, değerler genellikle çarpılır. Bu NA'nın başka bir değer kadar iyi yapması gereken bir şeydir. – Shape