我有一个有两列的表:你是否生病(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
答案 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
结果的(位置)。