应用用户定义的函数,该函数将函数作为参数

时间:2017-02-16 16:25:21

标签: r apply user-defined-functions

如果用户定义的函数将函数作为参数,如何将用户定义的函数“应用”到数据框的每一行?

这是一个例子......假设我在数据框中有三列,每列包含整数。对于每一行,我想取最小整数并使用查找数据集将其转换为相应的字母。同样,使用max integer执行相同的任务。结果将是:

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

以下代码会导致: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))

...但是下面的代码(切换了最后两行)工作正常:

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))

......有谁知道为什么?

2 个答案:

答案 0 :(得分:0)

调用第一行后,指定myData $ MinVal。在下一行中,您将在数据框中的整行上构建最大值,包括新的MinVal列。

所以不要将函数应用于所有列,即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))

答案 1 :(得分:0)

使用dplyr即可:

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

或者分2步,首先计算函数,然后进行查找:

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

使用purrr即可:

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")