封装和传递列表&常量通过MAPPLY

时间:2017-06-14 20:13:38

标签: r

我在将两个列表和一个常量数据帧从父函数传递到R中的子函数时出现问题。

如果在所有函数之外创建数据框,则该函数可以访问外部数据框(" lookup_frame")并执行相应的操作。参见Code Block One。

如果数据框作为具有两个列表的常量传递,则该函数不起作用。参见代码块二。

如果在父函数中创建数据框,则子函数无法访问数据框(" lookup_frame_two")。见代码块三。

我尝试完成的大致代码块如下所示:

for(i = 1; i < n; i++) {
    result[i] <- function(list_one[i], list_two[i], data_frame)
}

Code Block One

#runs fine
df_one <- data.frame(a = numeric(3), b = numeric(3))
df_one$a <- c(1:3)
df_one$b <- c(2:4)

lookup_frame <- data.frame(value_one = numeric(3), value_two = character(3))
lookup_frame$value_one <- c(10:12)
lookup_frame$value_two <- c(1:3)

test_function <- function(x,y){
  return_frame <- data.frame(value = numeric(1), lookup_value_one = numeric(1), lookup_value_two = numeric(1))
  random_test <- x^2+y^2
  return_frame$value <- random_test

  if(random_test < 6){
    return_frame$lookup_value_one <- lookup_frame$value_one[1]
    return_frame$lookup_value_two <- lookup_frame$value_two[1]
  }  

  if(random_test >6){
    if(random_test < 14){
      return_frame$lookup_value_one <- lookup_frame$value_one[2]
      return_frame$lookup_value_two <- lookup_frame$value_two[2]
    }
  }

  if(random_test > 14){
    return_frame$lookup_value_one <- lookup_frame$value_one[3]
    return_frame$lookup_value_two <- lookup_frame$value_two[3]
  }
  return(return_frame)
}

test_output <- do.call(rbind, mapply(test_function, df_one$a, df_one$b, SIMPLIFY = FALSE))
View(test_output)

代码块二

#cannot pass the data frame in as a constant when the other two inputs are lists
test_function_two <- function(x, y, z = data.frame()){
  return_frame <- data.frame(value = numeric(1), lookup_value_one = numeric(1), lookup_value_two = numeric(1))
  random_test <- x^2+y^2
  return_frame$value <- random_test

  if(random_test < 6){
    return_frame$lookup_value_one <- z$value_one[1]
    return_frame$lookup_value_two <- z$value_two[1]
  }  

  if(random_test >6){
    if(random_test < 14){
      return_frame$lookup_value_one <- z$value_one[2]
      return_frame$lookup_value_two <- z$value_two[2]
    }
  }

  if(random_test > 14){
    return_frame$lookup_value_one <- z$value_one[3]
    return_frame$lookup_value_two <- z$value_two[3]
  }
  return(return_frame)
}
#does not work
test_output_two <- do.call(rbind, mapply(test_function_two, df_one$a, df_one$b, lookup_frame, SIMPLIFY = FALSE))

Code Block Three

#cannot access the data frame in the parent function which calls the subfunction
test_function_three <- function(x,y){
  return_frame <- data.frame(value = numeric(1), lookup_value_one = numeric(1), lookup_value_two = numeric(1))
  random_test <- x^2+y^2
  return_frame$value <- random_test

  if(random_test < 6){
    return_frame$lookup_value_one <- lookup_frame_two$value_one[1]
    return_frame$lookup_value_two <- lookup_frame_two$value_two[1]
  }  

  if(random_test >6){
    if(random_test < 14){
      return_frame$lookup_value_one <- lookup_frame_two$value_one[2]
      return_frame$lookup_value_two <- lookup_frame_two$value_two[2]
    }
  }

  if(random_test > 14){
    return_frame$lookup_value_one <- lookup_frame_two$value_one[3]
    return_frame$lookup_value_two <- lookup_frame_two$value_two[3]
  }
  return(return_frame)
}

test_function_four <- function(){
  lookup_frame_two <- data.frame(value_one = numeric(3), value_two = character(3))
  lookup_frame_two$value_one <- c(10:12)
  lookup_frame_two$value_two <- c(1:3)

  test_output_two <- do.call(rbind, mapply(test_function_three, df_one$a, df_one$b, SIMPLIFY = FALSE))
  return(test_output_two)
}
#does not work
test_if_four_works <- test_function_four()

1 个答案:

答案 0 :(得分:0)

mapply要求list参数MoreArgs。 如果您将最后一行更改为:

,代码块2将起作用
test_output_two <- do.call(rbind,mapply(test_function_two, df_one$a, df_one$b, MoreArgs=list(z=lookup_frame),SIMPLIFY = FALSE))

由于函数test_function_three的关闭不包含lookup_frame_two

的定义,因此预计Code BLock Three会失败