2017-05-24 4 views
1

Ich versuche, Antworten mit einem Vektor zu rekodieren, der die richtigen Antworten enthält. Ich machte eine for-Schleife, die eine neue Spalte (mit der codierten Antwort) in jeder Schleife unter Verwendung eines Vektors mit den möglichen Namen für die neuen Spalten erzeugt.Übergeben Sie einen Vektor mit zu mutierenden Namen, um mehrere neue Spalten zu erstellen

Es scheint jedoch, dass muate keine Vektoren mit Namen erhält. Ich habe einige verschiedene Vektoren und einige paste0() Kombinationen ausprobiert, aber nichts scheint zu funktionieren.

Hier mein reproduzierbarer Code ist:

library(dplyr) 
library(tibble) 

correct = c(4, 5, 2, 2, 2, 3, 3, 5, 4, 5, 2, 1, 3, 4, 2, 2, 2, 4, 3, 1, 1, 5, 4, 1, 3, 2) 

sub1 = c(3, 5, 1, 5, 4, 3, 2, 5, 4, 3, 4, 4, 4, 1, 5, 1, 4, 3, 3, 4, 3, 2, 4, 2, 3, 4) 

df = t(data.frame(sub1)) 
colnames(df) = paste0("P", 1:26) 

new_names = paste0("P", 1:26, "_coded") 

for(i in 1:26){ 


    df = as.tibble(df) %>% 
    mutate(new_names = case_when(.[i] == correct[i] ~ 1, 
        .[i] != correct[i] ~ 0, 
        T ~ 9999999)) 

    print(df) # to know what's going on. 

} 

Auch weiß ich, dass .dots Namen in einem Vektor empfangen kann (glaube ich), aber ich verstehe nicht ganz, wie es im Innern mutiert mit case_when verwenden().

Andere Möglichkeiten, um neue Spalten mit dem umcodiert Wert sind auch willkommen zu erstellen

UPDATE: P26_COD mit möglichen Werten 1 (falls korrekt: der ursprüngliche Datenrahmen mit 26 neuen Spalten, P1_COD wäre Meine erwartete Ausgabe) und 0 (falls falsch).

So etwas (ich habe gerade vier Spalten mit 1s und 0s als Beispiel erstellt).

df %>% 
    mutate(P1_COD = 1, 
     P2_COD = 0, 
     P3_COD = 1, 
     P4_COD = 1) 
+1

Warum die extrem breite Form? In der langen Form ist es einfach: 'data_frame (richtig, sub1, cod = as.integer (richtig == sub1))' – alistaire

+0

Ich empfehle das nicht, aber wenn Sie es in breiter Form behalten wollen, sollte dies funktionieren: ' df <- cbind (df, setNames (as.data.frame (t (wie.numerisch (mapply (\ '== \', df, richtig)))), nm = paste0 (colnames (df), "_COD"))) '. –

Antwort

1

Die Daten sind nicht in einem Format, das am besten dplyr behandelt. Ich würde vorschlagen, Ihre Daten auf longitudinales Format umzustellen, und dann wird der case_when trivial und keine for-Schleife wird benötigt.

siehe andere Dokumentation für tidyr bezüglich Datenformat bei tidyverse.org documentation

Hier ein Beispiel für die „längs“ Format einschließlich Ihrer Beispieldaten ist. Ich fügte auch ein paar andere Themen mit zufälligen Antworten hinzu.

library(tidyverse) 
responses <- data_frame(
    subject = rep(1:3, each = 26), 
    qNum = rep(1:26, 3), 
    response = c(sub1, 
       sample(5, 26, replace = T), 
       sample(5, 26, replace = T))) 

Die Antworten können erstellt werden und dann zusammengefügt:

answers <- data_frame(
    qNum = 1:26, 
    answer = correct) 
df <- left_join(responses, answers) 

nächstes die Antworten punkten dplyr::case_when mit:

df <- df %>% mutate(score = case_when(response == answer ~ 1, 
           TRUE ~ 0)) 

Anmerkung: die TRUE ~ 0 zunächst verwirrend sein kann. Er gibt an, was mit den verbleibenden Werten geschehen soll, wenn die erste Bedingung FALSE ist. Das resultierende df/tibble:

# A tibble: 26 x 5 
    subject qNum response answer score 
    <dbl> <int> <dbl> <dbl> <dbl> 
1  1  1  3  4  0 
2  1  2  5  5  1 
3  1  3  1  2  0 
4  1  4  5  2  0 
5  1  5  4  2  0 
6  1  6  3  3  1 
7  1  7  2  3  0 
8  1  8  5  5  1 
9  1  9  4  4  1 
10  1 10  3  5  0 
# ... with 16 more rows 

Wenn Sie das "breit" Format konvertieren möchten, verwenden Sie tidyr::spread:

df %>% 
    select(-response, -answer) %>% 
    spread(qNum, score, sep = ".") 
# A tibble: 3 x 27 
    subject qNum.1 qNum.2 qNum.3 qNum.4 qNum.5 qNum.6 qNum.7 qNum.8 qNum.9 qNum.10 
* <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  1  0  1  0  0  0  1  0  1  1  0 
2  2  0  0  0  0  1  0  0  0  0  0 
3  3  0  0  0  0  1  0  0  0  0  0 
Verwandte Themen