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

时间:2014-09-04 09:32:36

标签: r

我有一个数据帧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尝试了get(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"))
}

3 个答案:

答案 0 :(得分:1)

这是一种使用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

答案 1 :(得分:1)

您的最后一行应为:

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

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

答案 2 :(得分:0)

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

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)