为数据帧中的每个现有列添加一个新列(用于异常值检测)



我有一个数据帧df。对于每一列,我想添加另一列,通过写TRUE(=异常值)或FALSE(=无异常值)来指示该值是在我的简单"异常值检测阈值"之内还是之外。

这是代码:

df <- read.csv("<FILE>", header=TRUE, sep=";")
column_names <- colnames(df[,-1])  # first column is actually row name
for(name in column_names) {  
  med <- median(df[[name]], na.rm = TRUE)
  std <- sd(df[[name]], na.rm = TRUE)
  max <- med + 3 * std
  min <- med - 3 * std
  newcol <- paste(name, "outlier", sep="_")  # create new column name
  df <- within(df, newcol <- ifelse(name < max & name > min,"FALSE","TRUE"))
}

不是为每个现有列添加一个新列,而是只添加一个名为"newcol"的列。在这种情况下,我如何访问变量newcol的实际值?Alread尝试得到(newcol)和[[newcol]]。

非常感谢你的帮助!

编辑:解决方案看起来像这个

df <- read.csv("<FILE>", header=TRUE, sep=";")
column_names <- colnames(df[,-1])  # first column is actually row name
for(name in column_names) {
  med <- median(df[[name]], na.rm = TRUE)
  std <- sd(df[[name]], na.rm = TRUE)
  max <- med + 3 * std
  min <- med - 3 * std
  newcol <- paste(name, "outlier", sep="_")
  df[[newcol]] <- with(df, ifelse(df[[name]] < max & df[[name]] > min,"FALSE","TRUE"))
}

最后一行应该是:

df[[newcol]] <- with(df, ifelse(...))

<-运算符假定newcol是列的实际名称,而不是包含此名称的变量。

这是一种使用data.table 的方法

require(data.table)
outlier <- function(x) {
  med <- median(x, na.rm = TRUE)
  std <- sd(x, na.rm = TRUE)
  max <- med + 3 * std
  min <- med - 3 * std
  return(!(x < max & x > min))
}
# df <- fread("<FILE>")
df <- data.table(x = rt(10, 5), y = rt(10, 5))
df[3, x := 100]
df[7, y := 100]
df[, paste(names(df), "outlier", sep="_") := lapply(.SD, outlier)]
df

您可以一次分配所有内容:

is_outlier <- function(x) {
    med <- median(x, na.rm = TRUE)
    std <- sd(x, na.rm = TRUE)
    max <- med + 3 * std
    min <- med - 3 * std
    !(x < max & x > min)
}
column_names <- names(df)[-1]
column_names_outlier <- paste(column_names, "outlier", sep="_")
df[column_names_outlier] <- lapply(df[column_names], is_outlier)

最新更新