【问题标题】:R replacing values of a column with those of other column's rowsR用其他列的行替换列的值
【发布时间】:2016-03-09 19:28:57
【问题描述】:

对于以下数据框:

df <- data.frame(name = c("July Doe", "John Doe", NA, "Jane Doe"), 
                 age = c(NA, NA, NA, 43), 
                 name1 = c(NA, NA, NA, "John Doe"), 
                 age1 = c(NA, NA, NA, 37), 
                 name2 = c(NA, NA, "July Doe", NA),
                 age2 = c(NA, NA, 7, NA))

提供:

          name age    name1 age1    name2 age2
    1 July Doe  NA     <NA>   NA     <NA>   NA
    2 John Doe  NA     <NA>   NA     <NA>   NA
    3     <NA>  NA     <NA>   NA July Doe    7
    4 Jane Doe  43 John Doe   37     <NA>   NA

namename1name2 匹配时,我需要将age 更改为对应的age1age2

到目前为止,我已经想出了这个(没有运气)。

df$age <- with(df, ifelse(is.na(df$age), ifelse(df$name %in% df$name1,
                          as.integer(df$age1), as.integer(df$age)), as.integer(df$age)))

如果任何高级 R 用户能解释一下,将不胜感激。我想保留剩余的 NA 并有类似的东西:

          name age    name1 age1    name2 age2
    1 July Doe   7     <NA>   NA     <NA>   NA
    2 John Doe  37     <NA>   NA     <NA>   NA
    3     <NA>  NA     <NA>   NA July Doe    7
    4 Jane Doe  43 John Doe   37     <NA>   NA

然后我可以处理删除只有 NA 的行和我不需要的列。

【问题讨论】:

    标签: r replace


    【解决方案1】:
    within(df,age[is.na(age)] <- c(age1,age2)[match(name[is.na(age)],c(as.character(name1),as.character(name2)))]);
    ##       name age    name1 age1    name2 age2
    ## 1 July Doe   7     <NA>   NA     <NA>   NA
    ## 2 John Doe  37     <NA>   NA     <NA>   NA
    ## 3     <NA>  NA     <NA>   NA July Doe    7
    ## 4 Jane Doe  43 John Doe   37     <NA>   NA
    

    您的代码无法正常工作的原因是,在内部 ifelse() 中,您正在测试 name 是否与 name1 中的 anywhere 匹配,但所选值最终会出现来自name的索引,而不是name1中匹配值的索引。

    【讨论】:

    • 谢谢你们(bgoldst 和 nicola)!!
    【解决方案2】:

    试试这个:

    res<-do.call(rbind,lapply(1:3,function(x) setNames(df[(2*x-1):(2*x)],c("name","age"))))
    res$age<-ave(res$age,res$name,FUN=function(x) x[!is.na(x)])
    do.call(cbind,split(res,(seq_len(nrow(res))-1) %/% (nrow(res)/3)))      
    #    0.name 0.age   1.name 1.age   2.name 2.age
    #1 July Doe     7     <NA>    NA     <NA>    NA
    #2 John Doe    37     <NA>    NA     <NA>    NA
    #3     <NA>    NA     <NA>    NA July Doe     7
    #4 Jane Doe    43 John Doe    37     <NA>    NA
    

    简而言之:首先你创建一个只有两列的data.framenameage),这样你就可以填补缺失的NA。最后,您恢复为原始格式。

    【讨论】:

      【解决方案3】:

      如果你想留在 ifelse...

      df$age <- ifelse(!is.na(df$age1[match(df$name, df$name1)]), 
                       df$age1[match(df$name, df$name1)],  
                       df$age2[match(df$name, df$name2)])
      

      【讨论】:

        猜你喜欢
        • 2018-02-18
        • 1970-01-01
        • 2019-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-20
        • 2013-10-29
        相关资源
        最近更新 更多