【问题标题】:Include columns that are mandatory in the dataframe在数据框中包含必填列
【发布时间】:2020-05-20 05:20:03
【问题描述】:

我在下面有一个数据框。

asd <- data.frame(a=c(1:10),b=c(11,20),c=(21:30),d=c(31:40),e=c(41,50),f=c(51,60))

以下是包含 asd 列名的 2 个向量

Column_list1 <- c("a","b","d")
Column_list2 <- c("c","e","f")

以下是列的强制列表

mandatory_column <- c("a","b","d","e")

现在实际上我的问题是当我尝试运行asd[Column_list1] 时,结果应该会抛出一条消息。因为必填列应该是c("a","b","d","e"),并且由于Column_list1 没有“e”,所以我需要打印消息“请同时包含“e”列”。这有可能实现吗?

预期输出

asd[Column_list1]
Please include column "e" as well
asd[mandatory_column]
    a  b  d  e
1   1 11 31 41
2   2 20 32 50
3   3 11 33 41
4   4 20 34 50
5   5 11 35 41
6   6 20 36 50
7   7 11 37 41
8   8 20 38 50
9   9 11 39 41
10 10 20 40 50

【问题讨论】:

  • stopifnot( all(mandatory_column %in% colnames(asd)) )?
  • 你是想写一个函数还是什么?您希望在哪里进行此项检查?
  • 我正在编写一个闪亮的应用程序。因此,如果我运行 asd[column_list1],它应该会显示一条消息“请同时选择 e 列”
  • @r2evans ,我尝试了stopifnot(all(mandatory_column %in% Column_list1)) 并得到了这个错误Error: all(mandatory_column %in% Column_list1) is not TRUE。而不是这个错误,我可以有“请同时选择 e 列”
  • 使用asd[union(mandatory_column, Column_list1)]之类的不是更方便吗?

标签: r


【解决方案1】:

如果您想弄乱对象 asd 的类,可以想到 S3 方法。

`[.special` <- function(x, i, ..., mandatory = mandatory_column){
  on.exit({
    cols_missing <- setdiff(mandatory, i)
    if(length(cols_missing) > 0){
      msg <- paste(sQuote(cols_missing), collapse = ", ")
      msg <- paste("Please include columns", msg)
      warning(msg)
    }
  })
  NextMethod(x, i, ...)
}


Column_list1 <- c("a","b","d")
Column_list2 <- c("c","e","f")
mandatory_column <- c("a","b","d","e")

第一次调用仍然调用[.data.frame方法。

asd[Column_list1]

现在调用[.special 方法。它对数据进行子集化并给出警告。

class(asd) <- c("special", class(asd))
asd[Column_list1]
asd[Column_list2]
asd[mandatory_column]

【讨论】:

  • 这不适用于asd[,Column_list1],其中缺少i。尤其是在data.framedata.tabletbl_df 不完全同意[1] 的含义的情况下,我想知道这是否应该对另一个论点的存在更加稳健。
【解决方案2】:
mandatory_columns <- c("cyl", "disp", "gear", "quux")
stopifnot(all(mandatory_columns %in% colnames(mtcars)))
# Error: all(mandatory_columns %in% colnames(mtcars)) is not TRUE

或者:

missingfields <- setdiff(mandatory_columns, colnames(mtcars))
if (length(missingfields)) {
  stop("missing fields: ", paste(sQuote(missingfields), collapse = ", "))
}
# Error: missing fields: 'quux'


### with a subset of mtcars, demonstrating more missing columns:
missingfields <- setdiff(mandatory_columns, colnames(mtcars)[1:4])
if (length(missingfields)) {
  stop("missing fields: ", paste(sQuote(missingfields), collapse = ", "))
}
# Error: missing fields: 'gear', 'quux'

如果您使用shiny 并希望在不停止程序的情况下进行验证/消息,请使用validateneedreq

  output$my_table <- renderTable({
    validate(need(req(all(mandatory_columns %in% names(mtcars))), "Missing columns"))
    asd[,mandatory_columns]
  })

【讨论】:

  • 真棒@r2evans,它工作。我可以问最后一个问题,如果没有错误,它应该执行 asd[Column_list1],意味着 Column_list1 中的值存在于 Mandatory_column 中?有可能吗?
  • "如果没有错误,它应该执行" ...如果代码没有停止,则带有stop的块之后的任何代码都将继续运行。我错过了什么?
猜你喜欢
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-02
  • 2018-12-20
  • 1970-01-01
相关资源
最近更新 更多