2017-02-16 1 views
1

Wie kann ich eine benutzerdefinierte Funktion für jede Zeile eines Datenrahmens "anwenden", wenn die benutzerdefinierte Funktion eine Funktion als Argument übernimmt?Wenden Sie eine benutzerdefinierte Funktion an, die die Funktion als Argument akzeptiert

Hier ist ein Beispiel ... Angenommen, ich habe drei Spalten in einem Datenrahmen, die jeweils ganze Zahlen enthalten. Für jede Zeile möchte ich die minimale Ganzzahl verwenden und sie mithilfe eines Such-Datasets in einen entsprechenden Buchstaben konvertieren. Führen Sie die gleiche Aufgabe mit der maximalen Ganzzahl aus. Ergebnis wäre dies:

 
Col1 | Col2 | Col3 | MaxVal | MinVal | 
------------------------------------- 
1  2  1  B  A 
4  4  1  F  A 
5  6  2  F  B 

Der folgende Code bewirkt: Error in $<-.data.frame(*tmp*, "MaxVal", value = integer(0)) : replacement has 0 rows, data has 3

myData <- data.frame("Col1" = c(1, 4, 5), "Col2" = c(2, 6, 6), "Col3" = c(1, 1, 2)) 
numberToLetterData <- data.frame("Number" = 1:6, "Letter" = c("A", "B","C","D","E","F")) 

GetMinOrMaxForRow <- function(x, refData, functionToUse){ 
    refData$Letter[refData$Number == functionToUse(x)] 
} 

myData$MinVal <- apply(myData, 1, FUN = function(x) GetMinOrMaxForRow(x = x, refData = numberToLetterData, functionToUse = min)) 
myData$MaxVal <- apply(myData, 1, FUN = function(x) GetMinOrMaxForRow(x = x, refData = numberToLetterData, functionToUse = max)) 

... aber der folgende Code (mit den letzten beiden Zeilen geschaltet) funktioniert:

myData <- data.frame("Col1" = c(1, 4, 5), "Col2" = c(2, 6, 6), "Col3" = c(1, 1, 2)) 
numberToLetterData <- data.frame("Number" = 1:6, "Letter" = c("A", "B","C","D","E","F")) 

GetMinOrMaxForRow <- function(x, refData, functionToUse){ 
    refData$Letter[refData$Number == functionToUse(x)] 
} 

myData$MaxVal <- apply(myData, 1, FUN = function(x) GetMinOrMaxForRow(x = x, refData = numberToLetterData, functionToUse = max)) 
myData$MinVal <- apply(myData, 1, FUN = function(x) GetMinOrMaxForRow(x = x, refData = numberToLetterData, functionToUse = min)) 

... Weiß jemand warum?

+0

Af Wenn Sie die erste Zeile aufrufen, ordnen Sie myData $ MinVal zu. In der nächsten Zeile erstellen Sie das Maximum über die gesamte Zeile in Ihrem Datenrahmen, einschließlich der neuen MinVal-Spalte. – c0bra

Antwort

0

Nachdem Sie die erste Zeile aufgerufen haben, weisen Sie myData $ MinVal zu. In der nächsten Zeile erstellen Sie das Maximum über die gesamte Zeile in Ihrem Datenrahmen, einschließlich der neuen MinVal-Spalte.

Also wenden Sie die Funktion nicht auf alle Spalten an, d. H. Nur myData [, 1: 3].

myData <- data.frame("Col1" = c(1, 4, 5), "Col2" = c(2, 6, 6), "Col3" = c(1, 1, 2)) 
numberToLetterData <- data.frame("Number" = 1:6, "Letter" = c("A", "B","C","D","E","F")) 

GetMinOrMaxForRow <- function(x, refData, functionToUse){ 
    refData$Letter[refData$Number == functionToUse(x)] 
} 

myData$MinVal <- apply(myData[,1:3], 1, FUN = function(x) GetMinOrMaxForRow(x = x, refData = numberToLetterData, functionToUse = min)) 
myData$MaxVal <- apply(myData[,1:3], 1, FUN = function(x) GetMinOrMaxForRow(x = x, refData = numberToLetterData, functionToUse = max)) 
0

Mit dplyr Sie tun können:

myData %>% 
    rowwise %>% 
    mutate(minVal = lookup[min(Col1, Col2, Col3)], 
     maxVal = lookup[max(Col1, Col2, Col3)]) 

Oder in 2 Schritten, so zunächst die Funktion zu berechnen und dann die Nachschlag tun:

myData %>% 
    rowwise %>% 
    mutate(minVal = min(Col1, Col2, Col3), 
     maxVal = max(Col1, Col2, Col3)) %>% 
    mutate_at(vars(minVal, maxVal), function(x) lookup[x]) 

purrr Verwenden Sie tun können:

require(purrr) 
lookup <- setNames(LETTERS[1:6], 1:6) 
myData %>% 
    by_row(~lookup[min(.[1:3])], .collate = "cols", .to = "minVal") %>% 
    by_row(~lookup[max(.[1:3])], .collate = "cols", .to = "maxVal") 
Verwandte Themen