2010-12-30 14 views
6
hinzu

Ich habe Daten aus einer Datei in einen Datenrahmen in R importiert. Es ist so etwas.Wie füge ich eine Spalte in einem Datenrahmen in R

Name  Count Category 
A   100  Cat1 
C   10  Cat2 
D   40  Cat1 
E   30  Cat3 
H   3  Cat3 
Z   20  Cat2 
M   50  Cat10 

So, jetzt will ich die Kategorie Spalte hinzuzufügen auf die Werte in der Spalte Name je. So etwas wie wenn Name = (A, D), Kategorie = 'Cat1' usw.

Dies ist nur ein einfaches Beispiel, das ich gebe. Ich habe eine große Anzahl von Namen und Kategorien, deshalb möchte ich eine kompakte Syntax. Wie kann ich das machen?

Edit: Ich habe das Beispiel geändert, um meinen Bedürfnissen besser zu entsprechen, da der Name alles nicht numerisch sein kann. Tut mir leid, dass ich vorher nicht zu klar war.

Antwort

2

Sie eine Karte verwenden können. (AKTUALISIERT stringsAsFactors = FALSE verwenden)

df <- data.frame(Name = c('A', 'C', 'D', 'E', 'H', 'Z', 'M'), 
        Count = c(100,10,40,30,3,20,50), stringsAsFactors = FALSE) 
Categories <- list(Cat1 = c('A','D'), 
        Cat2 = c('C','Z'), 
        Cat3 = c('E','H'), 
        Cat10 = 'M') 
nams <- names(Categories) 
nums <- sapply(Categories, length) 
CatMap <- unlist(Map(rep, nams, nums)) 
names(CatMap) <- unlist(Categories) 

df <- transform(df, Category = CatMap[ Name ]) 
+0

+1 Schöne Verwendung von 'Map()'. Dies ist das zweite Mal in der Woche, dass jemand hier 'Map()' in einer Antwort verwendet hat und sie scheinen wirklich sehr nützlich zu sein. –

+0

@Gavin danke. Eigentlich hat mir dieser andere Post etwas über Map beigebracht! –

+0

@pchalasani Danke, dies ist eine gute Möglichkeit, die Umcodierung zu tun. Allerdings habe ich das versucht und die Zuordnung ist irgendwie falsch, wenn ich es in meinen tatsächlichen Daten getan habe. Das Beispiel, das Sie geben, funktioniert gut. Mögliche Gründe dafür? – sfactor

3

Sie können ifelse verwenden. Wenn Ihr Datenrahmen genannt wurden df Sie tun würden:

df$cat <- ifelse(df$name<100, "Ones", "Hundreds") 
df$cat <- ifelse(df$name<1000, df$cat, "Thousands") 
+0

Entschuldigung, ich hätte klarer sein sollen, also habe ich das Beispiel geändert, der Name kann ein beliebiger alphabetischer Wert sein, nicht numerisch. Aber danke, ich werde versuchen, eine Logik wie diese anzuwenden und zu sehen. – sfactor

2

[Update folgenden Kommentar der OP und verändert Q]

DF <- data.frame(Name = c("A","C","D","E","H","Z","M"), 
       Count = c(100,10,40,30,3,20,50), stringsAsFactors = FALSE) 
lookup <- data.frame(Name = c("A","C","D","E","H","Z","M"), 
        Category = paste("Cat", c(1,2,1,3,3,2,10), sep = ""), 
        stringsAsFactors = FALSE) 

den oben genannten Datenrahmen verwenden, können wir eine Datenbank merge tun. Sie müssen lookup für die NameCategory Kombinationen, die Sie wollen, einrichten, die in Ordnung ist, wenn es nicht eine sehr große Anzahl von Name s (Zumindest müssen Sie sie nur einmal in lookup auflisten und Sie müssen nicht tun es, um - eine Liste aller Cat1Name erste, usw.):

> merge(DF, lookup, by = "Name") 
    Name Count Category 
1 A 100  Cat1 
2 C 10  Cat2 
3 D 40  Cat1 
4 E 30  Cat3 
5 H  3  Cat3 
6 M 50 Cat10 
7 Z 20  Cat2 
> merge(DF, lookup, by = "Name", sort = FALSE) 
    Name Count Category 
1 A 100  Cat1 
2 C 10  Cat2 
3 D 40  Cat1 
4 E 30  Cat3 
5 H  3  Cat3 
6 Z 20  Cat2 
7 M 50 Cat10 

Eine Option ist die Indizierung:

foo <- function(x) { 
    out <- character(length = length(x)) 
    chars <- c("Ones", "Tens", "Hundreds", "Thousands") 
    out[x < 10] <- chars[1] 
    out[x >= 10 & x < 100] <- chars[2] 
    out[x >= 100 & x < 1000] <- chars[3] 
    out[x >= 1000 & x < 10000] <- chars[4] 
    return(factor(out, levels = chars)) 
} 

Eine Alternative, die Skala s ist besser,

bar <- function(x, cats = c("Ones", "Tens", "Hundreds", "Thousands")) { 
    out <- cats[floor(log10(x)) + 1] 
    factor(out, levels = cats) 
} 
0

Check-out:

  • cut()
  • recode() im car Paket
0

Vielleicht einfacher und besser lesbar ifelse und% in% Verwendung:

df <- data.frame(Name = c('A', 'C', 'D', 'E', 'H', 'Z', 'M'), 
Count =c(100,10,40,30,3,20,50), stringsAsFactors = FALSE) 

cat1 = c("A","D") 
cat2 = c("C","Z") 
cat3 = c("E","H") 
cat10 = c("M") 

df$Category = ifelse(df$Name %in% cat1, "Cat1", 
       ifelse(df$Name %in% cat2, "Cat2", 
       ifelse(df$Name %in% cat3, "Cat3", 
       ifelse(df$Name %in% cat10, "Cat10", 
       NA)))) 

    Name Count Category 
1 A 100  Cat1 
2 C 10  Cat2 
3 D 40  Cat1 
4 E 30  Cat3 
5 H  3  Cat3 
6 Z 20  Cat2 
7 M 50 Cat10 
Verwandte Themen