尝试替换值时,“在数据帧的下标分配中不允许缺少值”

时间:2014-04-30 19:15:50

标签: r

我有一个有两列的表:你是否生病(H01)和生病天数(H03)。但是,如果H01 == false,则生病的天数为NA,我想将其设置为0.当我这样做时:

test <- pe94.person[pe94.person$H01 == 12,]
test$H03 <- 0

工作正常。但是,我想替换原始数据帧中的值。然而,这失败了:

pe94.person[pe94.person$H01 == 12,]$H03 <- 0

它返回:

> pe94.person[pe94.person$H01 == 12,]$H03 <- 0
Error in `[<-.data.frame`(`*tmp*`, pe94.person$H01 == 12, , value = list( : 
  missing values are not allowed in subscripted assignments of data frames

知道为什么会这样吗?对于它的价值,这是一个频率表:

> table(pe94.person[pe94.person$H01 == 12,]$H03)

 2  3  5 28 
 3  1  1  1 

6 个答案:

答案 0 :(得分:29)

这是由于H01变量缺失。

> x <- data.frame(a=c(NA,2:5), b=c(1:5))
> x
   a b
1 NA 1
2  2 2
3  3 3
4  4 4
5  5 5
> x[x$a==2,]$b <- 99
Error in `[<-.data.frame`(`*tmp*`, x$a == 1, , value = list(a = NA_integer_,  : 
  missing values are not allowed in subscripted assignments of data frames

分配无效,因为x$a缺少值。

完成第一部作品:

> z <- x[x$a==2,]
> z$b <- 99
> z <- x[x$a==2,]
> z
    a  b
NA NA NA
2   2  2

但那是因为[<-函数显然无法处理其提取索引中的缺失值,即使[可以:

> `[<-`(x,x$a==2,,99)
Error in `[<-.data.frame`(x, x$a == 2, , 99) : 
  missing values are not allowed in subscripted assignments of data frames

相反,请在执行作业时尝试指定!is.na(x$a)部分:

> `[<-`(x,!is.na(x$a) & x$a==2,'b',99)
   a  b
1 NA  1
2  2 99
3  3  3
4  4  4
5  5  5

或者,更常见的是:

> x[!is.na(x$a) & x$a==2,]$b <- 99
> x
   a  b
1 NA  1
2  2 99
3  3  3
4  4  4
5  5  5

请注意,the documentation

中描述了此行为
  

替换方法可用于通过指定不存在的列来添加整列,在这种情况下,列将添加到数据框的右边缘,并且数字索引必须与现有指数挂钩。另一方面,可以在当前最后一行之后的任何行添加行,并且列中将填充缺少的值。 不允许替换索引中的值。

答案 1 :(得分:7)

您可以像ifelse一样使用

pe94.person$foo <- ifelse(!is.na(pe94.person$H01) & pe94.person$H01 == 12, 0, pe94.person$H03)

检查foo是否符合您的条件,然后继续直接将其分配给pe94.person$H03。我发现为它分配一个新变量更安全,并且通常在后续分析中使用它。

答案 2 :(得分:3)

列中某处可能有NA导致错误。在特定列而不是整个数据框上运行索引。

movies[movies$Actors == "N/A",] = NA #ERROR
movies$Actors[movies$Actors == "N/A"] = NA #Works

答案 3 :(得分:2)

只需使用subset()功能即可从字符串中排除所有NA

它的作用为x[subset & !is.na(subset)]。看看这个数据:

> x <- data.frame(a = c(T,F,T,F,NA,F,T, F, NA,NA,T,T,F),
>                 b = c(F,T,T,F,T, T,NA,NA,F, T, T,F,F))

使用[运算符进行子集返回:

> x[x$b == T & x$a == F, ]

         a    b
2    FALSE TRUE
NA      NA   NA
6    FALSE TRUE
NA.1    NA   NA
NA.2    NA   NA

subset()做我们想要的事情:

> subset(x, b == T & a == F)

      a    b
2 FALSE TRUE
6 FALSE TRUE

更改子集变量的值:

> ss <- subset(x, b == T & a == F)
> x[rownames(ss), 'a'] <- T

> x[c(2,6), ]

     a    b
2 TRUE TRUE
6 TRUE TRUE

答案 4 :(得分:2)

以下作品。注意子设置中没有逗号:

x <- data.frame(a=c(NA,2:5), b=c(1:5))

x$a[x$a==2] <- 99

答案 5 :(得分:1)

我意识到这个问题很老了,但我认为最优雅的解决方案是使用which()函数:

 pe94.person[which(pe94.person$H01 == 12),]$H03 <- 0

应该做原始海报要求的。因为which()删除了NA,并仅保留TRUE结果的(位置)。