R - 函数只返回第一组传递的参数

时间:2015-12-16 02:17:26

标签: r

我在R遇到了一个奇怪的问题。

在附加的脚本中,我有两个数据帧,它们只是颠倒顺序(data_asc,data_desc)。然后我将具有相同参数的相同函数(fnDoIt)应用于两个数据帧,以在每个(成本)中创建新列。

该函数将字符串拆分为“|”然后创建一个数据帧并返回数据帧的“cost”元素。 parameter_desc包含以“|”分隔的参数名称而parameter_value包含以“|”分隔的参数值按顺序排列。

但是,当我运行脚本时,它会返回不同的值,具体取决于我的数据帧的顺序。它似乎返回第一组参数的结果。

我期望看到的是:

  • A -----价格|成本-------------- 10 | 7 ---------- 7
  • 乙-----价格|成本| TAX_RATE ----- 12 | 6 | 0.10 ----- 6

但我得到的(取决于数据框的顺序)是:

  • A -----价格|成本-------------- 10 | 7 ---------- 7
  • 乙-----价格|成本| TAX_RATE ----- 12 | 6 | 0.10 ----- 7

  • 乙-----价格|成本| TAX_RATE ----- 12 | 6 | 0.10 ----- 6
  • 甲-----价格| --------------成本10 | 7 ---------- 6

我不确定如何解决这个问题...非常感谢你们的任何帮助或见解

由于

stringsAsFactors=FALSE

fnDoIt = function(model
              , parameter_desc
              , parameter_value) {
  #process parameters
  #split string, then unlist
  parameter_desc = unlist(strsplit(parameter_desc
                                   , split = '|'
                                   , fixed = TRUE))

  #split string, then unlist, then convert to number
  parameter_value = as.numeric(unlist(strsplit(parameter_value
                                               , split = '|'
                                               , fixed = TRUE)))

  #build dataframe for parameters
  parameter = as.data.frame(t(parameter_value)) #transpose vector to horizontal
  names(parameter) = parameter_desc #rename columns

  fnDoIt = parameter$cost 
}

data = data.frame(model = c('A','B')
                  , parameter_desc = c('price|cost','price|cost|tax_rate')
                  , parameter_value = c('10|7','12|6|0.10'))

data_asc = data
data_desc = data[order(data$model, decreasing = TRUE),]

data_asc$cost = fnDoIt(data_asc$model
                       , data_asc$parameter_desc
                       , data_asc$parameter_value)

data_desc$cost = fnDoIt(data_desc$model
                        , data_desc$parameter_desc
                        , data_desc$parameter_value)

已更新

options(stringsAsFactors = FALSE)
fnDoIt = function(model
                  , production
                  , parameter_desc
                  , parameter_value) {

  #process parameters
  #split string, then unlist
  parameter_desc = unlist(strsplit(parameter_desc
                                   , split = '|'
                                   , fixed = TRUE))

  #split string, then unlist, then convert to number
  parameter_value = as.numeric(unlist(strsplit(parameter_value
                                               , split = '|'
                                               , fixed = TRUE)))

  if (model == 'A') {
    temp = parameter_value[parameter_desc == 'cost']
  } else if (model == 'B') {
    temp = parameter_value[parameter_desc == 'tax_rate']
  }

  fnDoIt = temp * production
}

data = data.frame(model = c('A','B','B')
                  , production = c(100,185,210)
                  , parameter_desc = c('price|cost','price|cost|tax_rate','price|cost|tax_rate')
                  , parameter_value = c('10|7','14|9|0.20','12|6|0.10'))

data$cost = ifelse(data$model == 'A'
                       , fnDoIt('A'
                                , data$production
                                , data$parameter_desc
                                , data$parameter_value)
                       , fnDoIt('B'
                                , data$production
                                , data$parameter_desc
                                , data$parameter_value))

我收到了错误:

  

在临时*生产中:较长的物体长度不是倍数   较短的物体长度

1 个答案:

答案 0 :(得分:0)

我认为这就是你要找的东西,

fnGetCost <- function(df){
  apply(df, 1, 
    function(r){
      parms <- unlist(strsplit(r[2], split="\\|")) 
      costIX <- which(parms == "cost")
      as.numeric(unlist(strsplit(r[3], split="\\|"))[costIX])
    })
}

data_asc$cost = fnGetCost(data_asc)

data_desc$cost = fnGetCost(data_desc)

您的原始解决方案正在考虑所有行。检查

的输出
unlist(strsplit(as.character(data_asc$parameter_desc)
            , split = '|'
            , fixed = TRUE))

因此,当您只返回其中一个列时,最终会有多个列名为cost的列。如果你真的想用你的功能,用

代替最后三行
parameter_value[parameter_desc == "cost"]

另请注意,由于数据列被强制转换为factor

,原始函数会引发错误