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

And*_*Min 33 r

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

test <- pe94.person[pe94.person$H01 == 12,]
test$H03 <- 0
Run Code Online (Sandbox Code Playgroud)

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

pe94.person[pe94.person$H01 == 12,]$H03 <- 0
Run Code Online (Sandbox Code Playgroud)

它返回:

> 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
Run Code Online (Sandbox Code Playgroud)

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

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

 2  3  5 28 
 3  1  1  1 
Run Code Online (Sandbox Code Playgroud)

Tho*_*mas 32

这是由于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
Run Code Online (Sandbox Code Playgroud)

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

放置第一部作品:

> z <- x[x$a==2,]
> z$b <- 99
> z <- x[x$a==2,]
> z
    a  b
NA NA NA
2   2  2
Run Code Online (Sandbox Code Playgroud)

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

> `[<-`(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
Run Code Online (Sandbox Code Playgroud)

因此,!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
Run Code Online (Sandbox Code Playgroud)

或者,更常见的是:

> 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
Run Code Online (Sandbox Code Playgroud)

请注意,此行为在文档中描述:

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

  • 您也可以使用`%in%`运算符代替`==`来避免丢失值,请参见[here](/sf/ask/1177569851/)以获得解释。因此,要么是[x [x $ a%in%2,] $ b &lt;-99`,要么以OPs为例“ pe94.person [pe94.person $ H01%in%12,] $ H03 &lt;-0”,工作。 (3认同)

inf*_*ner 9

您可以使用ifelse,像这样

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

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


Jam*_* L. 5

列中的某个位置可能NA导致错误。在特定列而不是整个数据帧上运行索引。

movies[movies$Actors == "N/A",] = NA #ERROR
movies$Actors[movies$Actors == "N/A"] = NA #Works
Run Code Online (Sandbox Code Playgroud)


小智 5

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

 pe94.person[which(pe94.person$H01 == 12),]$H03 <- 0
Run Code Online (Sandbox Code Playgroud)

应该按照原始海报的要求进行操作。因为which()删除 NA 并TRUE仅保留结果(的位置)。