首页 > 解决方案 > 根据条件 R 删除 DataFrame 中的值

问题描述

我有一个 4 列的数据框(在本例中放大)。大多数列的异常值明显大于数据框中的其他值。例如:一列(最大值为 99)具有 96、97、98、99 的异常值。这些异常值基本上表示“无响应”。这显然严重扭曲了数据,因此必须删除它们。我想删除异常值,但每个变量都有不同的最大值(和不同的异常值集),有些有小数。

96, 97, 98, 99 只能从具有保留值的列中删除。因此该函数必须知道哪些列具有每个特定的保留值分类。更多内容如下。

问题是,我不想“从所有列中删除”保留值,因为某些值可能意味着另一列中的其他内容。例如,在一个列中删除 996 可能意味着在另一列中具有重要意义,例如每小时工资/周。

它变得很棘手,因为有些人有小数点,比如每周工作小时数。例如。每周工作 37.5 小时的储备值为 999.6、999.7、999.8、999.9。该长度将被归类为 5.1。

我需要从数据框中删除这些保留值,但它们必须首先匹配相应的保留值长度。由于每一列都有不同的保留值,数据框的列名应该对应一个特定的保留值。

df <- data.frame("children#" = c(1,5,0,2,10), 
    "annual income" = c(700000.00,50000.65,30000.45,1000000.59,9999999.96), 
    "hour wage"= c(25.65,9999999.99,50.23,1000.72,65.16), 
    "hours worked/week" = c(148.5,77.0,64.2,25.9,999.7))

孩子的最大长度#为 2 年收入的最大长度为 10.2(总共 10,小数点后 2 个) 工资的最大长度为 10.2 每周工作的最大长度为 5.1(总共 5 个,小数点后 1 个)

始终为 4 个
保留值 如果最大长度 = 2,则删除保留值:96、97、98、99
如果最大长度 = 3,则删除保留值:996、997、998、999... 等带有实心数字

带小数:
如果最大长度 = 5.1,则删除保留值:999.6、999.7、999.8、999.9。
如果最大长度 = 10.2,则删除保留值:9999999.96、9999999.97、9999999.98、9999999.99

因此,我想弄清楚如何制作一个能够

  1. 找到最大长度
  2. 将相应的最大长度与正确的保留值连接起来
  3. 根据每列的最大长度从数据框中删除保留值

到目前为止,我有每列的最大长度和小数点。

我只需要一些帮助来将其连接到保留值并从数据框中删除这些保留值。

如果需要更多信息,请发表评论,如果需要我会进一步详细说明。

代码示例:对于保留值,我正在考虑创建一个单独的数据框并使用它来删除值。欢迎提出其他建议。

Find.Max.Length <- function(data){
# Check Max Length of each column
tmp <- data.frame(lapply(data, function(x) max(nchar(x, keepNA = F))))
tmp <- data.frame(t(tmp))
return(tmp)}
max.length <- Find.Max.Length(df)

Check.Decimal.Places <- function(x){
if((x %% 1) != 0){
nchar(strsplit(sub('0+$', '',as.character(x)), ".", fixed = TRUE)[[1]][[2]])
}else{
return(0)}
}

decimal <- data.frame(Check.Decimal.Places(df$random)) #<--- used to 
initialize the variable before the loop

for(i in seq_along(df)){
decimal[i] <- data.frame(Check.Decimal.Places(df[[i]]))}

decimal<- data.frame(t(decimal))
rownames(decimal) <- names(df)
length.df <- cbind(max.length, decimal)
names(length.df) <- c("Max Length", "Decimal Place")

length.df$NewVariableLength <- paste0(length.df$`Max Length`, sep= 
".",length.df$`Decimal Place`)

注意:length.df 数据框的行名称与原始数据框名称匹配。这可能是一种将两者联系在一起的方法吗?

可能有一种更快的方法来完成这一切,欢迎所有建议。

标签: rdataframeconditionalconditional-statementsmaxlength

解决方案


编辑:现在我明白你对“保留值”的意思-不应该计算的调查答案(例如“我不想回答这个问题”)

您在这里基本上有三种简单的方法,而无需搜索“整数长度”或其他过度工程:

  1. 最大值(即去掉四个最高值),
  2. 手动阈值(即,删除 X 以上的所有值),
  3. if-else 逻辑(即,如果 answer == X,则将其删除)。

构建数据集

您的数据不符合您的规范(“总是 4 个异常值”),所以我冒昧地对其进行了扩展。

df <- data.frame(
               "children" = c(1, 0, 96, 2, 10, 99, 98, 99),
               "annual_income" = c(700000.00, 50000.65, 30000.45, 1000000.59, 9999999.96, 9999999.97, 9999999.98, 9999999.99),
               "hour_wage"= c(25.65, 9999999.99, 50.23, 9999999.98, 9999999.99, 9999999.98, 1000.72, 65.16),
               "hours_worked_week" = c(148.5, 999.6, 77.0, 64.2, 999.9, 999.8, 25.9, 999.7)
               )

df
  children annual_income   hour_wage hours_worked_week
1        1     700000.00       25.65             148.5
2        0      50000.65  9999999.99             999.6
3       96      30000.45       50.23              77.0
4        2    1000000.59  9999999.98              64.2
5       10    9999999.96  9999999.99             999.9
6       99    9999999.97  9999999.98             999.8
7       98    9999999.98     1000.72              25.9
8       99    9999999.99       65.16             999.7

1. 最大值法(澄清后作废)

加载库

library(dplyr)
library(magrittr)

获取四个异常值

children_out <- tail(sort(df$children), 4)

用 NA 替换异常值

df[df$children %in% children_out,]
    %<>% mutate(children = NA)

检查数据集

df
  children annual_income   hour_wage hours_worked_week
1        1     700000.00       25.65             148.5
2        0      50000.65  9999999.99             999.6
3       NA      30000.45       50.23              77.0
4        2    1000000.59  9999999.98              64.2
5       10    9999999.96  9999999.99             999.9
6       NA    9999999.97  9999999.98             999.8
7       NA    9999999.98     1000.72              25.9
8       NA    9999999.99       65.16             999.7

警告:这种方法只有在每列总是有四个异常值时才有效。

2. 手动阈值

加载库

library(dplyr)
library(magrittr)

排除现有的 NA 并将 96 或以上的任何内容替换为 NA

df[!is.na(df$children) & df$children >=96, ] %<>%
    mutate(children = NA)

检查数据集

df
  children annual_income   hour_wage hours_worked_week
1        1     700000.00       25.65             148.5
2        0      50000.65  9999999.99             999.6
3       NA      30000.45       50.23              77.0
4        2    1000000.59  9999999.98              64.2
5       10    9999999.96  9999999.99             999.9
6       NA    9999999.97  9999999.98             999.8
7       NA    9999999.98     1000.72              25.9
8       NA    9999999.99       65.16             999.7

3. if-else 逻辑

加载库

library(dplyr)
library(magrittr)

保存“保留答案”

children_res <- c(96, 97, 98, 99)

用 NA 替换任何保留的答案(此处不需要现有的 NA)

df[df$children %in% children_res, ] %<>%
    mutate(children = NA)

检查数据集

df
  children annual_income   hour_wage hours_worked_week
1        1     700000.00       25.65             148.5
2        0      50000.65  9999999.99             999.6
3       NA      30000.45       50.23              77.0
4        2    1000000.59  9999999.98              64.2
5       10    9999999.96  9999999.99             999.9
6       NA    9999999.97  9999999.98             999.8
7       NA    9999999.98     1000.72              25.9
8       NA    9999999.99       65.16             999.7

4. 编辑:组合方法 1&3

加载库

library(dplyr)
library(magrittr)

获得“保留答案”

children_res <- tail(sort(unique(df$children)), 4)

用 NA 替换任何保留的答案(此处不需要现有的 NA)

df[df$children %in% children_res, ] %<>%
    mutate(children = NA)

警告:只有在每列中始终存在所有保留答案(例如,96、97、98 和 99)时,此方法才有效。如果不小心没有人回答“97”,这将不起作用。


推荐阅读