根据多个条件用预先存在的值替换 NA 值

Replace NA values with preexisting value based on multiple conditions

我正在处理以下数据。它与物品的尺寸和装运它们的盒子有关。

       Box_Height     Box_Length     Box_Width Item_Height Item_Length Item_Width
 1             NA             74             4          NA          NA         NA
 2             NA             42            NA           6          42          6
 3              6             NA            NA           6          22          6
 4              6             NA            NA           6          42          6
 5              6             NA            NA           6          42          6
 6             NA             NA            NA          NA          NA         NA

根据运输公司的说法,当其中一个箱子列有 NA 值时,这意味着该物品已经装在一个箱子里并且按原样运输。所以,我只需要用 Item_Height.

替换丢失的 Box_Height

我写了下面的代码来做到这一点:

df$Box_Height[is.na(df$Box_Height) & !is.na(df$Item_Height)] <- df$Item_Height

我最终尝试测试某行何时缺少框尺寸 特定项目尺寸 缺失,然后将缺少的框尺寸替换为项目尺寸。

我收到此错误:

Error in df$Box_Height[is.na(df$Box_Height) &  : 
  NAs are not allowed in subscripted assignments

这有点令人困惑,因为这是我要替换的内容。

如果有人对如何正确执行此操作或我哪里出错有任何建议,我将不胜感激。

尝试使用 ifelse() 应用相同的条件。

df$Box_Height <- ifelse(is.na(df$Box_Height) & !is.na(df$Item_Height), df$Item_Height, df$Box_Height)

ifelse() 函数要求您分别为条件为真和假的情况提供值,以确保向量长度匹配。用 [df$Box_Height 进行子集化可能会导致一个比 df$Item_Height 更短的向量,后者未被子集化。

我建议使用 tidyverse 语法。 并使用 if_else 而不是 ifelse.

library(tidyverse)

df <- tibble::tribble(
  ~Box_Height, ~Box_Length, ~Box_Width, ~Item_Height, ~Item_Length, ~Item_Width,
  NA,         74,          4,           NA,         NA,          NA,
  NA,         42,         NA,           6,          42,          6,
  6,          NA,         NA,           6,          22,          6,
  6,          NA,         NA,           6,          42,          6,
  6,          NA,         NA,           6,          42,          6,
  NA,         NA,         NA,           NA,         NA,          NA
)


df %>%
  mutate(Item_Height = if_else(
    is.na(Box_Height) & !is.na(Item_Height),
    Item_Height,
    Box_Height
  ))
#> # A tibble: 6 x 6
#>   Box_Height Box_Length Box_Width Item_Height Item_Length Item_Width
#>        <dbl>      <dbl>     <dbl>       <dbl>       <dbl>      <dbl>
#> 1         NA         74         4          NA          NA         NA
#> 2         NA         42        NA           6          42          6
#> 3          6         NA        NA           6          22          6
#> 4          6         NA        NA           6          42          6
#> 5          6         NA        NA           6          42          6
#> 6         NA         NA        NA          NA          NA         NA

此语法将同时对框的所有属性(尺寸)执行所需的操作

library(dplyr)
df %>% mutate(across(starts_with("Box"), ~ ifelse(is.na(.x), 
                                                  get(str_replace(cur_column(), "Box", "Item")),
                                                  .x)))

# A tibble: 6 x 6
  Box_Height Box_Length Box_Width Item_Height Item_Length Item_Width
       <dbl>      <dbl>     <dbl>       <dbl>       <dbl>      <dbl>
1         NA         74         4          NA          NA         NA
2          6         42         6           6          42          6
3          6         22         6           6          22          6
4          6         42         6           6          42          6
5          6         42         6           6          42          6
6         NA         NA        NA          NA          NA         NA