【问题标题】:Checking all non-numerical entries in a data.frame column and delete or substitute检查 data.frame 列中的所有非数字条目并删除或替换
【发布时间】:2016-02-23 09:08:38
【问题描述】:

我正面临一个具体的经验问题。我在 data.frame 列中有一个因变量。我可以轻松删除所有 NA 和所有非数字术语(不幸的是,这是一个开放式文本设计问题)。但是我想手动检查这些非数字条目中的一些字符串和其他信息(以进行可能的插补)。

df <- data.frame(list(A=c(1, 2, 3, 4, 5, 6, 7, 8, 9), B=c("40g", "< 2", "thx", "about 1", "1-2", "1/2", 3, 2.3, "two")))

  A       B
1 1     40g
2 2     < 2
3 3     thx
4 4 about 1
5 5     1-2
6 6     1/2
7 7       3
8 8     2.3
9 9     two

我认为没有特定的例程来列出所有非数字条目并询问我是否要保留它或用另一个值替换该条目。但也许这至少对整个专栏都是可能的?

最后我喜欢得到如下结构:

  A   B
1 1 0.4
2 2  NA
3 3  NA
4 4 1.0
5 5 1.5
6 6 NA
7 7 3.0
8 8 2.3
9 9 2.0

因为有非常不同的条目,我需要针对每种情况判断我是否可以假设一个数值(有时是平均值)。例如,我计算信息“1-2”或“1 到 2 之间”的平均值,并将“40g”等不同单位转换为“0.4”,但忽略所有无意义的字符串“banana”以及所有模棱两可的信息(“

报告的度量是消耗的数量。所以没有负单位。有时是克或公斤。

非常感谢!

更新

非常感谢 Tensibai 指定我的问题!以下是我如何创建一个有问题的非数字列表,这些列表可能是也可能不是潜在的插补候选者:

df <- data.frame(A=c(1, 2, 3, 4, 5, 6, 7, 8, 9), B=c("40g", "< 2", "thx", "about 1", "1-2", "1/2", 3, 2.3, "two"))
df$B <- as.character(df$B)
df$B[is.na( as.numeric(df$B) ) ]
[1] "40g"     "< 2"     "thx"     "about 1" "1-2"     "1/2"     "two"  

现在我想创建类似矢量的东西,例如

(0.4, NA, NA, 1, 1.5, NA, 2)

它应该在我的原始data.frame中的位置替换之前列出的条目。我不需要任何转换步骤的功能,但会手动完成!

【问题讨论】:

  • 1-2 是 -1 会更有意义,而 1/2 是如何变成 1.5 的?这不是0.5吗?为什么 40g 是 0.4?什么是40m?这里的测量单位是什么?总是公斤吗?
  • 你还有多少其他模式?
  • 这些是消耗的“部分”。 100 克被定义为一份,有时人们报告克而不是份。没有“40m”条目(我希望)!各种不同的条目...
  • 为什么 1/2 变成了 NA ?
  • 您必须为每个条目编写一个规则table(df$B) 会让您了解您的头痛程度。

标签: r select dataframe subset


【解决方案1】:

我会使用循环和 readline 来创建这样的新向量:

df <- data.frame(list(A=c(1, 2, 3, 4, 5, 6, 7, 8, 9), B=c("40g", "< 2", "thx", "about 1", "1-2", "1/2", 3, 2.3, "two")))
df$B <- as.character(df$B)

myscan <- function(x) {
 new <- vector("numeric",length(x))
 for(i in seq_along(x)) {
   new[i] <- readline(sprintf("Non numeric entry '%s' new value to set: ",x[i]))
 }
 as.numeric(new)
}

# get the entries 
notNum <- is.na( as.numeric(df$B) )
# Loop and ask for updates
df$B[notNum] <-  myscan(df$B[notNum])

运行时给出:

> df$B[notNum] <- as.numeric( myscan(df$B[notNum]) )
Non numeric entry '40g' new value to set: 0.4
Non numeric entry '< 2' new value to set: na
Non numeric entry 'thx' new value to set: ba
Non numeric entry 'about 1' new value to set: 1
Non numeric entry '1-2' new value to set: 1.5
Non numeric entry '1/2' new value to set: na
Non numeric entry 'two' new value to set: 2

然后我们将列返回到数字状态:

df$B <- as.numeric(df$B)

我们得到新的数据框:

> df
  A   B
1 1 0.4
2 2  NA
3 3  NA
4 4 1.0
5 5 1.5
6 6  NA
7 7 3.0
8 8 2.3
9 9 2.0

【讨论】:

  • 这太棒了!你让我今天一整天都感觉很好!最后,我必须用“df$B
  • 嗯,是的,这就是我在答案中写的,替换完成后返回数字......
猜你喜欢
  • 1970-01-01
  • 2014-03-20
  • 1970-01-01
  • 2012-06-13
  • 2019-09-23
  • 1970-01-01
  • 1970-01-01
  • 2012-04-07
  • 1970-01-01
相关资源
最近更新 更多