用NA替换数据帧中的星号

时间:2013-02-09 09:30:43

标签: r

这是我的数据框df

我正在尝试:

df=data.frame(rbind(c(1,"*","*"),c("*",3,"*"))
df2=as.data.frame(sapply(df,sub,pattern="*",replacement="NA"))

由于星号不起作用,但我在试图更换它时会生气。

4 个答案:

答案 0 :(得分:8)

如果您的*中只有ab*de(意味着它不像data.frame),那么您可以在没有regex的情况下执行此操作:

df[df == "*"] <- NA

答案 1 :(得分:8)

这里的两个解决方案都解决了工作场所中已存在的对象。如果可能(或至少在将来),您可以使用na.strings中的read.table参数。请注意,它是复数“字符串”,因此您应该能够指定多个字符作为NA值。

以下是一个示例:这只是将名为“readmein.txt”的文件写入当前工作目录并验证它是否存在。

cat("V1 V2 V3 V4 V5 V6 V7\n
2 * * * * * 2\n
1 2 * * * * 1\n", file = "readmein.txt")
list.files(pattern = "readme")
# [1] "readmein.txt"

这是read.table,其中na.strings参数正在运行。

read.table("readmein.txt", na.strings="*", header = TRUE)
#   V1 V2 V3 V4 V5 V6 V7
# 1  2 NA NA NA NA NA  2
# 2  1  2 NA NA NA NA  1

更新:工作场所中的对象

我看到另外两个答案的另一个问题:它们都会产生字符(或更确切地说是因子)变量,即使列可能是数字也是如此。

这是一个例子。首先,我们创建一个示例数据集。为了好玩,我添加了另一个要被视为NA的字符:“。”。

temp <- data.frame(
  V1 = c(1:3),
  V2 = c(1, "*", 3),
  V3 = c("a", "*", "c"),
  V4 = c(".", "*", "3"))
temp
#   V1 V2 V3 V4
# 1  1  1  a  .
# 2  2  *  *  *
# 3  3  3  c  3
str(temp)
# 'data.frame':  3 obs. of  4 variables:
#  $ V1: int  1 2 3
#  $ V2: Factor w/ 3 levels "*","1","3": 2 1 3
#  $ V3: Factor w/ 3 levels "*","a","c": 2 1 3
#  $ V4: Factor w/ 3 levels ".","*","3": 1 2 3

让我们制作副本,然后以我认为最明显的“R”方式解决这个问题:

temp1 <- temp
temp1[temp1 == "*"|temp1 == "."] <- NA

看起来确定...

temp1
#   V1   V2   V3   V4
# 1  1    1    a <NA>
# 2  2 <NA> <NA> <NA>
# 3  3    3    c    3

...但我认为V2和V4应该是数字....

str(temp1)
# 'data.frame':  3 obs. of  4 variables:
#  $ V1: int  1 2 3
#  $ V2: Factor w/ 3 levels "*","1","3": 2 NA 3
#  $ V3: Factor w/ 3 levels "*","a","c": 2 NA 3
#  $ V4: Factor w/ 3 levels ".","*","3": 1 NA 3

这是一种解决方法:

temp2 <- read.table(text = capture.output(temp), na.strings = c("*", "."))
temp2
#   V1 V2   V3 V4
# 1  1  1    a NA
# 2  2 NA <NA> NA
# 3  3  3    c  3
str(temp2)
# 'data.frame':  3 obs. of  4 variables:
#  $ V1: int  1 2 3
#  $ V2: int  1 NA 3
#  $ V3: Factor w/ 2 levels "a","c": 1 NA 2
#  $ V4: int  NA NA 3

更新2 :(又一个)替代

在其帮助页面上使用type.convert可能更合适,read.table被描述为“data.frame( lapply(temp, function(x) type.convert( as.character(x), na.strings = c("*", ".")))) 的帮助函数”。我没有计时,但我的猜测是它会比我上面提到的解决方法更快,并带来所有好处。

{{1}}

答案 2 :(得分:4)

你应该提出一个完整的可重复的例子,当你让它变得容易时,人们会更倾向于提供帮助。 Anywho ...

dat <- data.frame(a=c(1,2,'*',3,4), b=c('*',2,3,4,'*'))
> dat
  a b
1 1 *
2 2 2
3 * 3
4 3 4
5 4 *
> as.data.frame(sapply(dat,sub,pattern='\\*',replacement=NA))
     a    b
1    1 <NA>
2    2    2
3 <NA>    3
4    3    4
5    4 <NA>

答案 3 :(得分:1)

这可行(这是非常灵活的),但已经有其他很好的解决方案。 Arun的解决方案是我的典型方法,但为新R(使用命令行的经验很少)用户创建了replacer。对于任何有经验的人,我都不会推荐replacer

library(qdap)
replacer(dat, "*", NA)