2015-03-24 6 views
21

Ich habe seltsame Probleme mit dplyr und Kombination von group_by, muate und ifelse. Betrachten Sie die folgende data.framedplyr Fehler: seltsames Problem bei der Kombination von group_by, mutiere und ifelse. Ist es ein Fehler?

> df1 
    crawl.id group.id hits.diff 
1  1  1  NA 
2  1  2  NA 
3  2  2   0 
4  1  3  NA 
5  1  3  NA 
6  1  3  NA 

Wenn ich es den folgenden Code verwenden

library(dplyr) 
df1 %>% 
    group_by(group.id) %>% 
    mutate(hits.consumed = ifelse(hits.diff<=0,-hits.diff,0)) 

Aus irgendeinem Grund, den ich

Error: incompatible types, expecting a logical vector** 

jedoch erhalten, das Entfernen entweder group_by() oder ifelse alles wie erwartet funktioniert :

df1 %>% 
    mutate(hits.consumed = ifelse(hits.diff<=0,-hits.diff,0)) 

crawl.id group.id hits.diff hits.consumed 
1  1  1  NA   NA 
2  1  2  NA   NA 
3  2  2   0    0 
4  1  3  NA   NA 
5  1  3  NA   NA 
6  1  3  NA   NA 

df1 %>% 
    group_by(group.id) %>% 
    mutate(hits.consumed = -hits.diff) 

    crawl.id group.id hits.diff hits.consumed 
1  1  1  NA   NA 
2  1  2  NA   NA 
3  2  2   0    0 
4  1  3  NA   NA 
5  1  3  NA   NA 
6  1  3  NA   NA 

Ist es ein Fehler oder eine Funktion? Kann das jemand replizieren? Was ist das Besondere an dieser speziellen Kombination von group_by, mutate und ifelse, die es zum Scheitern bringt?

Meine eigene Forschung führte mich hier: https://github.com/hadley/dplyr/issues/464 was darauf hindeutet, dass es jetzt behoben werden sollte.

Hier ist dput(df1):

structure(list(crawl.id = c(1, 1, 2, 1, 1, 1), group.id = structure(c(1L, 
2L, 2L, 3L, 3L, 3L), .Label = c("1", "2", "3"), class = "factor"), 
    hits.diff = c(NA, NA, 0, NA, NA, NA)), .Names = c("crawl.id", 
"group.id", "hits.diff"), row.names = c(NA, -6L), class = "data.frame") 
+1

Es scheitert auch für mich. Es sieht so aus, als ob die Gruppe mindestens einen Nicht-NA-Wert benötigt, damit dies funktioniert. dh. 'df1 [2: 3,]%>% group_by (group.id)%>% muate (hits.consumed = ifelse (hits.diff <= 0, -hits.diff, 0))' hat funktioniert – akrun

+0

Ja, das bist du richtig. 'df1 [1: 3,]' scheitert noch 'df1 [2: 3,]' funktioniert. Es scheint eine Reinkarnation dieses alten dplyr-Problems 464 zu sein. – akhmed

+1

Sie konnten es als ein Problem ablegen – akrun

Antwort

33

es in as.numeric alle Wickeln Sie das Ausgabeformat zu erzwingen, so dass die NA s, die logical standardmäßig sind, nicht die Klasse der Ausgangsgröße außer Kraft setzen:

df1 %>% 
    group_by(group.id) %>% 
    mutate(hits.consumed = as.numeric(ifelse(hits.diff<=0,-hits.diff,0))) 

# crawl.id group.id hits.diff hits.consumed 
#1  1  1  NA   NA 
#2  1  2  NA   NA 
#3  2  2   0    0 
#4  1  3  NA   NA 
#5  1  3  NA   NA 
#6  1  3  NA   NA 

Ziemlich sicher, dass dies das gleiche Problem wie hier: Custom sum function in dplyr returns inconsistent results, da dieses Ergebnis legt nahe:

out <- df1[1:2,] %>% mutate(hits.consumed = ifelse(hits.diff <= 0, -hits.diff, 0)) 
class(out$hits.consumed) 
#[1] "logical" 
out <- df1[1:3,] %>% mutate(hits.consumed = ifelse(hits.diff <= 0, -hits.diff, 0)) 
class(out$hits.consumed) 
#[1] "numeric" 
+0

Danke! Du bist genau richtig! Ich stöbere das Problem # 489 und @romainfrancois Antwort - es sieht so aus, als ob dieses Verhalten durch inkonsistente Typen verursacht wurde, die von 'ifelse' für einige Gruppen zurückgegeben wurden: logisch und für einige Gruppen numerisch. Ihre Lösung löst sie, indem sie alles in Zahlenform umwandelt, bevor sie in gruppiertes mutieren eingegeben wird. Funktioniert perfekt! – akhmed

+0

Vielen Dank. Ich habe den ganzen Morgen damit zu kämpfen, an genau diesem Thema zu arbeiten! – eastafri

+0

@thelatemail, obige Abfrage funktionierte gut und gab mir das Ergebnis für die jeweilige Spalte, aber alle Spalten, die nur Alphabete haben, sind ohne Werte und alphanumerisch ist wie es ist und numerisch ist wie es ist. So erhalten Sie die Werte von Spalten. Suggest me – Pallavi

Verwandte Themen