2017-02-02 12 views
2

Ich habe Daten von einem Sport-Team-Tracking-Siegen/Verluste im Vergleich zu anderen Teams mit der folgenden Struktur:dplyr Mit Faktorvariable abhängig numerischen Variablen mutieren

Game TotalWins TotalLosses Team1Win Team1Loss Team2Win Team2Loss ... 
1 1   0   1  NA  NA  NA 
2 1   1   NA  NA  NA  1 
3 2   1   NA  NA  1  NA 
4 2   2   NA  1   NA  NA 
5 3   2   NA  NA  1  NA 
... 

Ich mag einen Faktor Variable erstellen, die das Team umfasst das Spiel gespielt wurde gegen, so dass die Daten wie folgt aussehen:

Game TotalWins TotalLosses Team1Win Team1Loss Team2Win Team2Loss Team 
1 1   0   1  NA  NA  NA  Team1 
2 1   1   NA  NA  NA  1   Team2 
3 2   1   NA  NA  1  NA  Team2 
4 2   2   NA  1   NA  NA  Team1 
5 3   2   NA  NA  1  NA  Team2 
... 

Mein Denken (nicht praktikabeler Code) ist im wesentlichen diese:

if (Team1Win == 1 | Team1Loss == 1), Team = "Team1" 
if (Team2Win == 1 | Team2Loss == 1), Team = "Team2" 

Ich habe wirklich Schwierigkeiten damit, dies in dplyr mit muate zu tun. Ich habe verschiedene Ansätze mit ifelse, recode usw. ausprobiert, aber ich bekomme entweder Fehler oder Ergebnisse, die nicht das sind, was ich will.

Was ist der richtige und effizienteste Weg, um dies in dplyr zu machen?

+0

'mutieren (Team = ifelse (is.na (Team1Win) & is.na (Team1Loss), "Team2", "Team1"))' – Vlo

+0

zu @ Hinzufügen Vlo des netten Kommentar: die [ ' ifelse'] (http://stat.ethz.ch/R-manual/R-devel/library/base/html/ifelse.html) Funktion ist eine große für diese Art von Anwendungsfall – bouncyball

+0

@Vlo, das ist eines der Dinge, die ich versuchte vor dem Posten (nur ich versuchte es mit nichtfehlenden Werten, weil es viele Teams gibt, die alle fehlen, nicht nur zwei wie in meinem Beispiel), und es wirft diesen Fehler: "Fehler in muate_impl (.data, dots): Argument" Ja "fehlt, ohne Standard" Irgendeine Idee, was ist los? –

Antwort

1

In einer ähnlichen Richtung zu anderen Antworten, aber mit einigen nützlichen Änderungen:

  • na.rm = TRUE in gather
  • sub funktioniert gut, keine Notwendigkeit für stringr
  • umfasst die voll Daten gemäß dem Ziel, mit einem full_join.
library(dplyr) 
library(tidyr) 

df = read.delim(text = 
"Game TotalWins TotalLosses Team1Win Team1Loss Team2Win Team2Loss 
1 1 0 1 NA NA NA 
2 1 1 NA NA NA 1 
3 2 1 NA NA 1 NA 
4 2 2 NA 1 NA NA 
5 3 2 NA NA 1 NA", sep = " ") 

df %>% 
    select(-starts_with("Total")) %>% 
    gather(Team, one, -Game, na.rm = TRUE) %>% 
    select(-one) %>% 
    mutate(Team = sub("Win|Loss", "", Team)) %>% 
    full_join(df, .) 

#> Joining, by = "Game" 
#> Game TotalWins TotalLosses Team1Win Team1Loss Team2Win Team2Loss Team 
#> 1 1   1   0  1  NA  NA  NA Team1 
#> 2 2   1   1  NA  NA  NA   1 Team2 
#> 3 3   2   1  NA  NA  1  NA Team2 
#> 4 4   2   2  NA   1  NA  NA Team1 
#> 5 5   3   2  NA  NA  1  NA Team2 
0

Dies könnte das sein, was Sie suchen. (Nicht nur für 2 Teams fest einprogrammiert)

# solution 1 : 
paste0("Team",ceiling(apply(df[-c(1:3)], 1, function(x) which(!is.na(x)))/2)) 
[1] "Team1" "Team2" "Team2" "Team1" "Team2" 

# solution 2: using a apply() {basically a for loop itself] 
apply(df[-c(1:3)], 1, function(x) gsub("(Team\\d)+.*", "\\1", colnames(df[-c(1:3)])[which(!is.na(x))])) 
# [1] "Team1" "Team2" "Team2" "Team1" "Team2" 

# solution 3: (long route to dplyr) [ you have indirectly taught me a lot in dplyr through my search for this solution] 
func <- function(x){ 
    y = which(x == 1)    # get the location of where 1 appears 
    z = rep(0, times = length(x)) # create a vector of 0's+location of 1 
    z[y] = y      # i.e. c(0,0,3,0,5) for Team2Win 
    z 
} 

df1 = df[-c(1:3)] %>% gather("key", "value", starts_with("Team")) %>% 
       group_by(key) %>% 
       dplyr::mutate(x = func(value)) %>% 
       filter(x != 0) %>% arrange(x) %>% select(key) 

df$newcol = gsub("(Team\\d+).*", "\\1", df1$key) 
+0

@AshLevitt bitte bewerten Sie unsere Bemühungen bei der Beantwortung Ihrer Frage: Apprecated http://StackOverflow.com/Help/Someone-answers –

0

Sie können es eine einfache Schleife mit:

x = colnames(df) 
df$team<- NA 

for (i in 1:nrow(df)) 
{ 
df$team[i] = x[which(df[i,]==1)] 
} 

Und dann am Ende können Sie trimmen „gewinnen“ und „Verlust“ mit folgenden Funktion:

df$team<- gsub("win", "",df$team) 
df$team<- gsub("loss", "",df$team) 
1

ich bin ein Sauger für dplyr Ansätze, um die Dinge im Moment so dass ich eine Lösung mit dplyr anzubieten, die aber viele Teams erweitert Sie haben könnten. Es verwendet auch tidyr und stringr wie hilfreich im Kommentar von apom unten hingewiesen.

library(dplyr) 
library(tidyr) 
library(stringr) 

df = read_delim(
"Game TotalWins TotalLosses Team1Win Team1Loss Team2Win Team2Loss 
1 1 0 1 NA NA NA 
2 1 1 NA NA NA 1 
3 2 1 NA NA 1 NA 
4 2 2 NA 1 NA NA 
5 3 2 NA NA 1 NA",delim = " ") 

df %>% 
    gather("Team",value,contains("Team")) %>% 
    filter(!is.na(value)) %>% 
    mutate(Team = str_replace_all(Team,c("Win" = "","Loss" = ""))) %>% 
    select(-value) 
+2

Sie müssten auch 'Bibliothek (Tidyr)' –

+0

@apom gut entdeckt, wird geändert – jamieRowen

+0

Vielen Dank! Dies ist hilfreich. –

0

Ich bin ziemlich sicher, dass Sie mehr als zwei Teams in Ihren Daten haben, und Team-Namen sind nicht generisch. Was Sie tun möchten, ist, zuerst die Daten in Long Form umzuformen und den entsprechenden Teamnamen zu extrahieren. So möchten Sie vielleicht wie folgt vorgehen.

library(dplyr) 
library(tidyr) 
new_df <- df %>% 
    gather(team,idx,Team1Win:Team100Loss) %>% 
    filter(!is.na(idx)) %>% 
    select(-idx) %>% 
    mutate(team = gsub("Win|Loss","",team)) 

Wenn Sie diese breiten Spalten behalten wollen, dann können Sie den neuen DF mit dem alten verbinden.

+0

Ich glaube, das ist ziemlich ähnlich zu meiner Antwort – jamieRowen

+0

Ich habe deine nicht gesehen, wenn ich es einlege. Tut mir leid. – Julius

Verwandte Themen