2017-05-11 2 views
1

Ich wäre dankbar für Vorschläge, wie ich meinen Code verbessern kann. Der zweite Versuch funktioniert und gibt die erforderliche Ausgabe, aber ich halte es für sehr mühsam. Vielleicht gibt es dafür eine einfachere Lösung.Kombinieren Sie mehrere Spalten mit NA-Werten in R, aber verwenden Sie nur NA, wenn keine der Spalten Daten enthält

Das ursprüngliche Dataset enthält 8 Spalten mit Informationen zu Bildschirmauflösungen. Jede Spalte stellt eine andere Gruppe von Fragen dar, in die die Teilnehmer nach dem Zufallsprinzip eingeteilt wurden. Dies bedeutet, dass NA eingefügt wurde, wenn die Lösungsfrage in diesem bestimmten Satz nicht gestellt wurde, obwohl der Teilnehmer sie möglicherweise in einer anderen Menge beantwortet hat.

Ich habe anonymisierter und vereinfachte Daten, um nur drei der ursprünglich acht Spalten Ich erwähne:

ID ResSet1 ResSet2 ResSet3 
1 NA NA NA 
2 NA NA NA 
3 NA NA NA 
4 NA NA NA 
5 NA 1280x800 NA 
6 NA NA NA 
7 NA NA NA 
8 NA NA NA 
9 NA 1440x900 NA 
10 NA NA 1366x768 
11 NA NA NA 
12 NA NA NA 
13 NA NA NA 
14 NA 1366x768 NA 
15 NA NA NA 
16 NA NA 1920x1080 
17 NA NA NA 
18 1600x1200 NA NA 
19 NA NA NA 
20 NA NA 1366x768 
21 NA NA 1440x900 
22 NA 1680x1050 NA 
23 1600x900 NA NA 
24 NA NA NA 
25 NA NA 1920x1080 
26 NA NA NA 
27 NA 1440x900 NA 
28 NA NA NA 
29 NA NA 1600x900 
30 1280x800 NA NA 

Mein Ziel ist es, alle Sätze in eine Spalte namens Resolutions zu kombinieren; Markieren Sie eine bestimmte Zeile jedoch nur dann als NA, wenn sie NA-Werte in allen Sätzen/Spalten enthält. Wenn ein Satz die Auflösung enthält, sollten nur Auflösungswerte in die Spalte geschrieben werden.

Ich versuchte das folgende Vertrauen auf dplyr und tidyr Pakete, hier sind meine zwei Versuche.

Der erste Versuch, mutieren und paste0 mit:

x = test %>% mutate(Resolution = paste0(ResSet1, ResSet2, ResSet3)) 

Dies führt in etwa wie folgt: (Ausgabe von Originaldaten)

x$Resolution 

1] "NANANANANANANA1366x768" "NANA1440x900NANANANANA" "NANANANANANA1344x840NA" "NANANANA1366x768NANANA" 
     [5] "NA1280x800NANANANANANA" "NANANANANANANA1366x768" "NANANANA1366x768NANANA" "NANANANANANA1536x864NA" 
     [9] "NA1440x900NANANANANANA" "NANANA1366x768NANANANA" "NANANANANANANA1280x800" "NANANANANA1366x768NANA" 
    [13] "NANA1408x792NANANANANA" "NA1366x768NANANANANANA" "NANANANANA1920x1080NANA" "NANANA1920x1080NANANANA" 

ich nicht geklappt habe Figur, wie so etwas wie rm zu tun .na Funktion während der Verwendung von paste0, also in meinem zweiten Versuch mit unite; Ich habe NA-Strings durch "" ersetzt und leere Zellen durch die richtige NA ersetzt.

x2 = test %>% unite(Resolution, ResSet1, ResSet2, ResSet3, 
        remove = TRUE, sep = "") %>% 
    mutate(Resolution = str_replace_all(Resolution, "NA", "")) %>% 
    mutate(Resolution = ifelse(Resolution == "", NA, Resolution)) 

Ergebnis wie folgt aussehen: (Ausgabe von Originaldaten)

x2$Resolution 

"1366x768" NA   "1280x800" "1366x768" "1366x768" "1366x768" NA   "1440x900" 

Das ist eigentlich das, was ich erreichen müssen; Die Lösung scheint mir jedoch nicht sehr elegant zu sein, und vielleicht gibt es dafür einen einfacheren Ansatz.

Vielen Dank für Anregungen.

Antwort

1

coalesce verwendet werden kann, den ersten nicht NA Wert der entsprechenden Werte von mehreren Vektoren wählen:

library(dplyr) 

df <- df %>% 
    mutate_at(vars(contains('ResSet')), as.character) %>% # ensure all are character, not factor 
    mutate(Resolutions = coalesce(ResSet1, ResSet2, ResSet3)) # coalesce 

tail(df) 
#> ID ResSet1 ResSet2 ResSet3 Resolutions 
#> 25 25  <NA>  <NA> 1920x1080 1920x1080 
#> 26 26  <NA>  <NA>  <NA>  <NA> 
#> 27 27  <NA> 1440x900  <NA> 1440x900 
#> 28 28  <NA>  <NA>  <NA>  <NA> 
#> 29 29  <NA>  <NA> 1600x900 1600x900 
#> 30 30 1280x800  <NA>  <NA> 1280x800 
0

Versuchen Sie Folgendes:

Verwendung:

df <- structure(list(ID = 1:30, ResSet1 = c(NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "1600x1200", NA, 
NA, NA, NA, "1600x900", NA, NA, NA, NA, NA, NA, "1280x800"), 
    ResSet2 = c(NA, NA, NA, NA, "1280x800", NA, NA, NA, "1440x900", 
    NA, NA, NA, NA, "1366x768", NA, NA, NA, NA, NA, NA, NA, "1680x1050", 
    NA, NA, NA, NA, "1440x900", NA, NA, NA), ResSet3 = c(NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, "1366x768", NA, NA, NA, NA, 
    NA, "1920x1080", NA, NA, NA, "1366x768", "1440x900", NA, 
    NA, NA, "1920x1080", NA, NA, NA, "1600x900", NA)), .Names = c("ID", 
"ResSet1", "ResSet2", "ResSet3"), class = "data.frame", row.names = c(NA, 
-30L)) 

Dann:

df$newcol <- 
    apply(df[,-1], 1, function(row) { 
    if(all(is.na(row))) return(NA) 
    else return(unique(row[!is.na(row)])) 
    }) 

gibt:

head(df) 
    ID ResSet1 ResSet2 ResSet3 newcol 
1 1 <NA>  <NA> <NA>  <NA> 
2 2 <NA>  <NA> <NA>  <NA> 
3 3 <NA>  <NA> <NA>  <NA> 
4 4 <NA>  <NA> <NA>  <NA> 
5 5 <NA> 1280x800 <NA> 1280x800 
6 6 <NA>  <NA> <NA>  <NA> 

Die Verwendung von unique hier wird durch die Tatsache begründet, dass Vorabend Obwohl es in Ihren Beispieldaten keine wiederholten Beobachtungen pro Zeile gibt, könnte dies in Ihren tatsächlichen Daten der Fall sein (soweit ich Ihre Problembeschreibung verstanden habe). Wenn das nicht der Fall ist, können Sie unique weglassen. Wenn es zwei Auflösungen gibt, die sich unterscheiden, möchten Sie es möglicherweise in z. list oder etwas anderes.

1

Sie tun kann dies leicht in der Basis R - Ich gehe davon aus, dass die erste Spalte ID und alle anderen sind Auflösung Spalten:

df$res <- df[cbind(seq_len(nrow(df)), max.col(!is.na(df[-1]))+1)] 
0

Sie diese mit einer Kombination aus gather und right_join erreichen können. Bei diesem Ansatz müssen Sie nicht alle Spalten manuell angeben, falls Ihr data.frame nur aus ID und den anderen acht Spalten besteht.

library(tidyverse) 

df %>% 
    gather(key, resolution, -ID) %>% 
    select(-key) %>% 
    na.omit() %>% 
    right_join(df) 
#> Joining, by = "ID" 
#> ID resolution ResSet1 ResSet2 ResSet3 
#> 1 1  <NA>  <NA>  <NA>  <NA> 
#> 2 2  <NA>  <NA>  <NA>  <NA> 
#> 3 3  <NA>  <NA>  <NA>  <NA> 
#> 4 4  <NA>  <NA>  <NA>  <NA> 
#> 5 5 1280x800  <NA> 1280x800  <NA> 
#> 6 6  <NA>  <NA>  <NA>  <NA> 
#> 7 7  <NA>  <NA>  <NA>  <NA> 
#> 8 8  <NA>  <NA>  <NA>  <NA> 
#> 9 9 1440x900  <NA> 1440x900  <NA> 
#> 10 10 1366x768  <NA>  <NA> 1366x768 
#> 11 11  <NA>  <NA>  <NA>  <NA> 
#> 12 12  <NA>  <NA>  <NA>  <NA> 
#> 13 13  <NA>  <NA>  <NA>  <NA> 
#> 14 14 1366x768  <NA> 1366x768  <NA> 
#> 15 15  <NA>  <NA>  <NA>  <NA> 
#> 16 16 1920x1080  <NA>  <NA> 1920x1080 
#> 17 17  <NA>  <NA>  <NA>  <NA> 
#> 18 18 1600x1200 1600x1200  <NA>  <NA> 
#> 19 19  <NA>  <NA>  <NA>  <NA> 
#> 20 20 1366x768  <NA>  <NA> 1366x768 
#> 21 21 1440x900  <NA>  <NA> 1440x900 
#> 22 22 1680x1050  <NA> 1680x1050  <NA> 
#> 23 23 1600x900 1600x900  <NA>  <NA> 
#> 24 24  <NA>  <NA>  <NA>  <NA> 
#> 25 25 1920x1080  <NA>  <NA> 1920x1080 
#> 26 26  <NA>  <NA>  <NA>  <NA> 
#> 27 27 1440x900  <NA> 1440x900  <NA> 
#> 28 28  <NA>  <NA>  <NA>  <NA> 
#> 29 29 1600x900  <NA>  <NA> 1600x900 
#> 30 30 1280x800 1280x800  <NA>  <NA> 
Verwandte Themen