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



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

如果数据框

是在所有函数外部创建的,则该函数可以访问外部数据框("lookup_frame"(并执行相应的操作。请参阅代码块 1。

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

如果数据框

是在父函数中创建的,则子函数无法访问数据框("lookup_frame_two"(。请参阅代码块三。

我试图完成的近似代码块如下所示:

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

代码块一

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

代码块三

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

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

test_output_two <- do.call(rbind,mapply(test_function_two, df_one$a, df_one$b, MoreArgs=list(z=lookup_frame),SIMPLIFY = FALSE))

Code BLock Three 上的失败是意料之中的,因为函数 test_function_three 的闭包不包含对lookup_frame_two的防御

最新更新