首页 > 解决方案 > 如何编写函数来返回绘图和对象(data.frame)?

问题描述

描述和目标:在 R Studio 中,我想定义一个函数,如果给定 data.frame 的列包含过高的缺失值份额,则该函数由截断值百分比定义。此函数应返回有关子集 data.frame 的信息(剩余列数和缺失案例的剩余份额)以及子集 data.frame 本身以供进一步分析。此外,应该有一个选项可以使用vis_miss()同名包的功能来可视化剩余的缺失案例。

使用的包:

library(tidyverse)
library(vismiss)

数据:

my.data <- tibble(col_1 = c(1:5),
                  col_2 = c(1,2,NA,NA,NA))

我的功能:

cut_cols <- function(df, na.perc.cutoff, vis_miss=FALSE) {
  df <- df[lapply(df, function(x) sum(is.na(x)) / length(x)) < na.perc.cutoff]
  cat(paste0("Remaining cols: ", ncol(df)),
      paste0("\nRemaining miss: ", paste0(round(sum(is.na(df)) / prod(dim(df)) * 100, 2), "%\n")))
  if (vis_miss==TRUE) {return(vis_miss(df[1:nrow(df),c(1:ncol(df))], warn_large_data=F))}
  df
}

测试:

cut_cols(my.data, 0.5, vis_miss = F) # without visualization
cut_cols(my.data, 0.5, vis_miss = T) # with visualization

问题: 正如您在上面的示例中可能已经看到的那样,只有第一行 wherevis_miss = F实际上返回 data.frame 而不是第二行 where vis_miss = T。我认为这是因为额外的if () {}子句,它返回一个情节,然后结束该过程而不打印df。有没有办法防止这种情况发生,以便第一行也返回新的 data.frame?

标签: rdataframefunction

解决方案


您怀疑该if(){}子句阻止 df 打印是正确的。我认为return()阻止任何功能进一步运行。如果是这种情况,那么最好将它放在任何函数的末尾。

此外,用于print(df)确保您的函数输出您的数据框。以下是对您的代码的一些更改

cut_cols <- function(df, na.perc.cutoff, vis_miss=FALSE) {
  df <- df[lapply(df, function(x) sum(is.na(x)) / length(x)) < na.perc.cutoff]
  cat(paste0("Remaining cols: ", ncol(df)),
      paste0("\nRemaining miss: ", paste0(round(sum(is.na(df)) / prod(dim(df)) * 100, 2), "%\n")))
  print(df)
  if (vis_miss==TRUE) {return(vis_miss(df[1:nrow(df),c(1:ncol(df))], warn_large_data=F))}
}

cut_cols(my.data, 0.5, vis_miss = T)

如果您感兴趣,这是另一种选择。您可以将 df 和 plot 分配给一个列表,然后调用该列表。

cut_cols <- function(df, na.perc.cutoff, vis_miss=FALSE) {
  df <- df[lapply(df, function(x) sum(is.na(x)) / length(x)) < na.perc.cutoff]
  cat(paste0("Remaining cols: ", ncol(df)),
      paste0("\nRemaining miss: ", paste0(round(sum(is.na(df)) / prod(dim(df)) * 100, 2), "%\n")))

  # empty list
  list_ <- c()
  # assign df to first index of list
  list_[[1]] <- df

  if (vis_miss==TRUE){
    plot <- vis_miss(df[1:nrow(df),c(1:ncol(df))], warn_large_data=F)
    # assign plot to second index in list
    list_[[2]] <- plot
  }
  return(list_)
}

output <- cut_cols(my.data, 0.5, vis_miss = T)

调用output将打印 df 和 plot。output[[1]]将只打印 df。output[[2]]将只打印情节。


推荐阅读