1

这是我的数据框 df

我正在努力:

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

由于星号,它不起作用,但我很生气试图替换它。

4

4 回答 4

8

如果你只是有*(意思是它不像ab*de)你的data.frame,那么,你可以在没有的情况下做到这一点regex

df[df == "*"] <- NA
于 2013-02-09T09:36:37.793 回答
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("*", "."))))
于 2013-02-09T09:41:30.390 回答
5

你应该提出一个完整的可重复的例子,当你让他们变得容易时,人们会更愿意提供帮助。随便...

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>
于 2013-02-09T09:34:35.997 回答
1

这可以工作(它非常灵活),但已经有其他很棒的解决方案了。Arun 的解决方案是我的典型方法,但它是replacer为新的 R(命令行经验很少)用户创建的。我不会向replacer任何有一点经验的人推荐。

library(qdap)
replacer(dat, "*", NA)
于 2013-02-09T22:48:24.487 回答