2014-09-04 41 views
1

我有一个数据框df。对于每一列,我想通过写入TRUE(= outlier)或FALSE(= no outlier)来添加另一列,指示该值是在我的简单“异常值检测阈值”之内还是之外。在数据框中为每个现有数据框添加一个新列(用于异常值检测)

下面的代码:

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")) 
} 

回答

1

你的最后一行应读的方法:

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

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

+0

对不起,想通了。在我最初的问题中添加了解决方案。 感谢您的帮助! – chrmar 2014-09-04 10:27:45

+0

@chrmar您不应编辑问题以包含答案。如果您有不同的答案,请将其作为解决方案发布,以便社区可以为无法应付此问题的未来用户高举/低投票。 – MrFlick 2014-09-04 13:49:49

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 
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) 
相关问题