【问题标题】:When trying to replace values, "missing values are not allowed in subscripted assignments of data frames"尝试替换值时,“数据框的下标分配中不允许缺少值”
【发布时间】:2020-08-21 18:23:57
【问题描述】:

我有一个包含两列的表:您是否生病 (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 

【问题讨论】:

  • 很可能是因为您在H01 列中有NAs。请注意您尚未使用的 table 的 useNA 参数。此外,引用[ 中的列可能比使用$ 更好(在风格上)。
  • 有道理;我想的也差不多。我将如何更换 NA?抱歉,我对 R 没有太多经验。
  • pe94.person$H01[is.na(p94.person$H01)] &lt;- value 可能。
  • 嗯,但我不能替换所有的 NA,因为一些 NA 只是表示缺失值(即该人没有回应)。另外,我有点困惑为什么将其拆分(使用测试变量),但在一行中执行却不行?
  • 因为当你拆分它时,R 不必推断NA 的索引与哪一行对应;您只是告诉它重新分配特定列中的所有值。

标签: r


【解决方案1】:

这是由于缺少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

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

> `[<-`(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 中描述了此行为:

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

【讨论】:

  • 您也可以通过使用%in% 运算符而不是== 来绕过缺失值,有关说明,请参阅here。因此,x[x$a %in% 2,]$b &lt;- 99 或 OP 示例 pe94.person[pe94.person$H01 %in% 12,]$H03 &lt;- 0 都可以。
【解决方案2】:

你可以使用ifelse,像这样

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

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

        只需使用subset() 函数从字符串中排除所有NA

        它以x[subset &amp; !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
        

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-07-08
            • 1970-01-01
            • 1970-01-01
            • 2018-02-17
            • 2017-10-20
            • 1970-01-01
            相关资源
            最近更新 更多