检查 data.frame 列中的所有非数字条目并删除或替换
Checking all non-numerical entries in a data.frame column and delete or substitute
我面临一个具体的经验问题。我在 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”或 "between 1 and 2" 的平均值,并将不同的单位(如“40g”)转换为“0.4”,但忽略所有无意义的字符串 "banana" 以及所有模棱两可的信息(“ <2")。
报告的度量是消耗量。所以没有负单位。有时是克或公斤。
非常感谢!
更新
非常感谢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。我不需要任何转换步骤的功能,但会手动完成!
我会使用循环和 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
然后我们return将列设置为数值状态:
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
我面临一个具体的经验问题。我在 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”或 "between 1 and 2" 的平均值,并将不同的单位(如“40g”)转换为“0.4”,但忽略所有无意义的字符串 "banana" 以及所有模棱两可的信息(“ <2")。
报告的度量是消耗量。所以没有负单位。有时是克或公斤。
非常感谢!
更新
非常感谢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。我不需要任何转换步骤的功能,但会手动完成!
我会使用循环和 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
然后我们return将列设置为数值状态:
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