2

我正在寻找一种优雅的方式来返回列的值,如果它存在并且(一个向量)NA或者NULL如果它不存在。直接解决它会产生一个undefined columns错误,使用子集会产生一个 0 列数据框。有没有一种优雅的内置方式,没有定义一个函数来做到这一点?

> example(data.frame)
# output omitted
> head(d, 1)
  x y fac
1 1 1   A
> head(d['x'], 1)
  x
1 1

# Works when accessing column using $
> head(d$z, 1)
NULL
# Not satisfactory
> head(d['z'], 1)
Error in `[.data.frame`(d, "z") : undefined columns selected
> head(d[colnames(d) == 'z'], 1)
data frame with 0 columns and 1 rows

编辑:当然,这条单线可以完成这项工作。我正在寻找更多的 R-ish 方式。

> safe.index <- function(df, n)
     if (any(n %in% colnames(df))) df[n] else rep(NA, nrow(df))
> head(safe.index(d, 'z'), 1)
[1] NA
4

2 回答 2

3

解决此问题的一种方法是在尝试子集之前测试'z'列名中是否存在:d

if('z' %in% names(d)){
  head(d['z'],1)
} else {
  NA
}

另一种方法是使用tryCatch和条件处理:

# Actually, the following line defining e isn't really necessary.
# e <- simpleError("stopped")
safe.index <- function(df, n){
  tryCatch(df[n], error = function(e)return(rep(NA, nrow(df))))
}
head(safe.index(d, 'z'), 1)
# [1] NA

head(safe.index(d, 'x'), 1)
#   x
# 1 1

一个潜在的缺点是,无论错误如何,上述解决方案tryCatch都会返回一个向量,而不仅仅是在不是列名的情况下。NAn

于 2012-06-19T09:59:03.680 回答
2

关于什么:

data <- data.frame(x = 1:2, y = 2:3, z = 3:4)
outCol <- function(df, name){
  unlist(ifelse(name %in% names(df),df[name],list(rep(NA,nrow(df)))))
}
outCol(data, 'x')
[1] 1 2
outCol(data, 'u')
[1] NA NA
于 2012-06-19T09:58:32.447 回答