【问题标题】:R: replacing NAs in a data.frame with values in the same position in another dataframeR:用另一个数据帧中相同位置的值替换data.frame中的NA
【发布时间】:2017-05-01 16:52:41
【问题描述】:

我有一个带有一些 NA 值的数据框:

dfa <- data.frame(a=c(1,NA,3,4,5,NA),b=c(1,5,NA,NA,8,9),c=c(7,NA,NA,NA,2,NA))
dfa

我想用另一个数据帧中相同位置的值替换 NA:

dfrepair <- data.frame(a=c(2:7),b=c(6:1),c=c(8:3))
dfrepair

我试过了:

dfa1 <- dfa

dfa1 <- ifelse(dfa == NA, dfrepair, dfa)
dfa1

但这不起作用。

【问题讨论】:

    标签: r dataframe na


    【解决方案1】:

    你可以这样做:

    dfa <- data.frame(a=c(1,NA,3,4,5,NA),b=c(1,5,NA,NA,8,9),c=c(7,NA,NA,NA,2,NA))
    dfrepair <- data.frame(a=c(2:7),b=c(6:1),c=c(8:3))
    dfa[is.na(dfa)] <- dfrepair[is.na(dfa)]
    dfa
    
      a b c
    1 1 1 7
    2 3 5 7
    3 3 4 6
    4 4 3 5
    5 5 8 2
    6 7 9 3
    

    【讨论】:

    • 如果创建新表而不是修改dfa:replace(dfa, is.na(dfa), dfrepair[is.na(dfa)])
    【解决方案2】:

    在 tidyverse 中,您可以使用 purrr::map2_df,它是 mapply 的严格二元版本,简化为 data.frame,以及 dplyr::coalesce,它将其第一个参数中的 NA 值替换为相应的第二个。

    library(tidyverse)
    
    dfrepair %>% 
        mutate_all(as.numeric) %>%    # coalesce is strict about types
        map2_df(dfa, ., coalesce)
    
    ## # A tibble: 6 × 3
    ##       a     b     c
    ##   <dbl> <dbl> <dbl>
    ## 1     1     1     7
    ## 2     3     5     7
    ## 3     3     4     6
    ## 4     4     3     5
    ## 5     5     8     2
    ## 6     7     9     3
    

    【讨论】:

      【解决方案3】:

      我们可以使用base R 中的Map 对两个数据集进行逐列比较

      dfa[] <- Map(function(x,y) {x[is.na(x)] <- y[is.na(x)]; x}, dfa, dfrepair)
      dfa
      #  a b c
      #1 1 1 7
      #2 3 5 7
      #3 3 4 6
      #4 4 3 5
      #5 5 8 2
      #6 7 9 3
      

      【讨论】:

        【解决方案4】:
        dfa <- data.frame(a=c(1,NA,3,4,5,NA),b=c(1,5,NA,NA,8,9),c=c(7,NA,NA,NA,2,NA))
        dfa
        dfrepair <- data.frame(a=c(2:7),b=c(6:1),c=c(8:3))
        dfrepair 
        library(dplyr)
        coalesce(as.numeric(dfa), as.numeric(dfrepair))
        
          a b c
        1 1 1 7
        2 3 5 7
        3 3 4 6
        4 4 3 5
        5 5 8 2
        6 7 9 3
        

        dplyr 中的代码是用 C++ 编写的,因此在大多数情况下速度更快。另一个重要的优势是coalesce 以及许多其他dplyr 函数在SQL 中是相同的。使用dplyr,您可以通过在R 中编码来学习SQL。 ;-)

        【讨论】:

        • as.numerics 对我来说是错误的,尽管 coalesce(dfa, dfrepair) 出人意料地确实有效(文档只讨论向量,而不是整个 data.frames)并且没有抱怨不同的类型。
        • 感谢您的 as.numeric。 ;-) data.frame 是列表和向量的列表。在上述情况以及许多其他情况下,它只是一个包含数字的向量列表。因此,在我们的例子中,它与矩阵非常相似。如果 data.frame 包含递归列表,我的代码将不会运行。
        • 一个data.frame可能看起来像一个矩阵,但底层结构却大不相同。 data.frame 是一维向量的列表,而矩阵是具有二维的单个向量。大多数为向量设计的函数不适用于 data.frames; coalesce 中的子集必须是偶然的。
        • A &lt;- matrix(1:9, nrow = 3) is.vector(A) 呈现FALSE。根据这个测试,矩阵不是 R 中的单个向量。
        • 来自the language definition:“矩阵和数组是简单的向量,带有属性dim 和可选的dimnames 附加到向量。”例如。 x &lt;- diag(3); attributes(x) &lt;- NULL; x 列表也是向量(通用的,不是原子的),例如is.vector(list(1)),使这个词令人困惑。 is.vector 只检查名称以外的属性,这就是为什么is.vector(iris) 返回FALSE,即使typeof(iris) 返回"list"。更好的检查:purrr::is_vector(diag(3)); purrr::is_atomic(diag(3))TRUETRUE.
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-29
        • 2015-04-25
        相关资源
        最近更新 更多