2016-10-07 3 views
0

ein Datenrahmen Gegeben:Anwenden verschiedener Funktionen auf Datenrahmen Spalten auf den Spaltennamen in Abhängigkeit mit einem Muster übereinstimmen

l$`__a` <- data.frame(`__ID` = stringi::stri_rand_strings(10, 1), 
col = stringi::stri_rand_strings(10, 1), check.names = F) 

und zwei unterstützenden Funktionen:

prefixColABC <- function(dfCol) { 
paste0("ABC_", dfCol) 
} 

prefixColDEF <- function(dfCol) { 
    paste0("DEF_", dfCol) 
} 

Wie kann ich die erste Funktion anwenden für Datenrahmenspaltennamen, die mit __ anstarren und die zweite für alle anderen Spalten?

Um dieses Problem zu lösen, ich dachte, dass ich mit __ beginnend zuerst alle Spalten mit Namen Teilmenge würde, gelten prefixColABC ihnen, dann alle anderen Teilmenge und prefixColDEF für sie gelten. Dann würde ich cbind() verwenden, um alle Spalten wieder in einem Datenrahmen zusammenzufassen.

Hier einige meiner Fortschritte:

Hier ist, wie die erste Funktion auf alle Spalten angewendet werden kann:

as.data.frame(apply(l$`__a`, 2, prefixColABC)) 

Und hier ist, wie ich die Spalten Teilmenge kann. Alle beginnend mit Spaltennamen mit __:

l$`__a`[ grep(pattern = "^__", l$`__a`), 1 ] 

Ich weiß nicht, wie alle anderen Spalten der Teilmenge, die nicht dieses Muster passen. Und ich weiß nicht, wie die Bedingung in der Anweisung gelten einzurichten

Ich denke, diese Frage ähnlich wie mir, aber nicht wählen Sie die Spalten basierend auf einem Muster übereinstimmen: R Applying different functions to different data frame columns

Antwort

2

Versuchen Sie, diese unter der Annahme,

hasPrefix <- grepl("^__", names(dd)) 
dd[, hasPrefix] <- lapply(dd[, hasPrefix, drop = FALSE], prefixColABC) 
dd[, !hasPrefix] <- lapply(dd[, !hasPrefix, drop = FALSE], prefixColDEF) 

geben:

> dd 
    __ID col 
1 ABC_G DEF_x 
2 ABC_n DEF_U 
3 ABC_c DEF_G 
4 ABC_O DEF_X 
5 ABC_p DEF_E 
6 ABC_U DEF_j 
7 ABC_M DEF_G 
8 ABC_0 DEF_l 
9 ABC_V DEF_i 
10 ABC_B DEF_u 

, dass der Eingangsdatenrahmen genannt ddHinweis: Der Eingang dd, vor der Modifikation ist:

dd <- structure(list(`__ID` = structure(c(4L, 6L, 3L, 7L, 8L, 9L, 5L, 
1L, 10L, 2L), .Label = c("0", "B", "c", "G", "M", "n", "O", "p", 
"U", "V"), class = "factor"), col = structure(c(8L, 7L, 2L, 9L, 
1L, 4L, 2L, 5L, 3L, 6L), .Label = c("E", "G", "i", "j", "l", 
"u", "U", "x", "X"), class = "factor")), .Names = c("__ID", "col" 
), row.names = c(NA, -10L), class = "data.frame") 
+0

Ihre Lösung ist sehr hilfreich, danke! Ich versuche es anzupassen, um den ursprünglichen Datenrahmen nicht zu überschreiben. Könntest du mir auch dabei helfen? Ich versuche jetzt, einen leeren Datenrahmen mit der gleichen Struktur auf diese Weise zu erstellen: 'dd2 <- dd [0,]' und dann fülle es mit Daten aus dem 'apply' Befehl, aber ich bekomme diesen Fehler " Ersatzelement 1 hat 10 Zeilen, um 0 Zeilen zu ersetzen ". Soll ich stattdessen "vapply" verwenden, um sicherzustellen, dass immer ein Spaltenvektor in den Datenrahmen eingefügt wird? – Bobby

+0

Ich habe auch versucht, eine Funktion zu schreiben, die Ihr Beispiel verwendet, aber es gibt keinen Datenrahmen mit zwei Spalten zurück, wie ich erwartet hatte. Hast du irgendwelche Hinweise dazu zu geben? 'processOneDF <- function (dfName) { dfName [ "__ ID"] <- lapply (dfName [ "__ID", fallen = FALSE], prefixColABC) dfName [ "col"] <- lapply (dfName [, "col", drop = FALSE], prefixColDEF) } l5 <- l l5 $ '__a' <- processOneDF (l5 $' __a') ' – Bobby

Verwandte Themen