在R中,将值NA替换为另一列的值

37

我想将dfABy中列A中的NA值,替换为基于列year的年份所对应的列B的值。例如我的df是:

                 >dfABy 
                 A    B   Year
                 56   75  1921
                 NA   45  1921
                 NA   77  1922
                 67   41  1923
                 NA   65  1923

我即将参加的活动结果是:

                 > dfABy
                 A    B   Year
                 56   75  1921
                *45*  45  1921
                *77*  77  1922
                 67   41  1923
                *65*  65  1923

附注:* 表示每年将列A中的值替换为列B中的值


2
强相关:https://dev59.com/WGIk5IYBdhLWcg3wdd_Y(也许可以考虑作为重复问题?) - Gregor Thomas
5个回答

45

现已根据@Max的更正进行了修正。 (在最初实现中原始版本有效)

新的dplyr函数coalesce可以真正简化这些情况。

library(dplyr)

dfABy %>% 
    mutate(A = coalesce(A,B))

不起作用,但其他答案已经纠正了它。 - Sebastian Hesse
1
现在已经更正了 - 我们确实不应该让过时的答案挂在那里。 - GGAnderson

34

在R的词汇表中,最容易阅读和理解的答案可能是使用ifelse。因此,借用Richard的数据框,我们可以进行如下操作:

df <- structure(list(A = c(56L, NA, NA, 67L, NA),
                     B = c(75L, 45L, 77L, 41L, 65L),
                     Year = c(1921L, 1921L, 1922L, 1923L, 1923L)),.Names = c("A", 
                                                                                                                            "B", "Year"), class = "data.frame", row.names = c(NA, -5L))
df$A <- ifelse(is.na(df$A), df$B, df$A)

24

GGAnderson提供的解决方案返回了一个错误信息。然而,在mutate()内部使用它就可以正常工作。

df <- structure(list(A = c(56L, NA, NA, 67L, NA),
                     B = c(75L, 45L, 77L, 41L, 65L),
                     Year = c(1921L, 1921L, 1922L, 1923L, 1923L)),
                .Names = c("A", "B", "Year"), 
                class = "data.frame", 
                row.names = c(NA, -5L))
df
df%>% 
  coalesce(A,B) #returns error

df %>%
mutate(A = coalesce(A,B)) #works

(我是Stackoverflow的新手;我的声望不够高,不能直接评论GGAnderson的回答)


7
您可以使用简单的替换方法,将[<-NA元素进行子集替换。
df$A[is.na(df$A)] <- df$B[is.na(df$A)]

或者,使用within()函数。
within(df, A[is.na(A)] <- B[is.na(A)])

两者都提供

   A  B Year
1 56 75 1921
2 45 45 1921
3 77 77 1922
4 67 41 1923
5 65 65 1923

数据:

df <- structure(list(A = c(56L, NA, NA, 67L, NA), B = c(75L, 45L, 77L, 
41L, 65L), Year = c(1921L, 1921L, 1922L, 1923L, 1923L)), .Names = c("A", 
"B", "Year"), class = "data.frame", row.names = c(NA, -5L))

5

简单易学

library(dplyr)

dfABy %>%
  mutate(A_new = 
           A %>% 
             is.na %>%
             ifelse(B, A) )

1
为什么要添加新列?如果你使用mutate(A = ...)而不是A_new,那么你将会替换掉第一列的值,这也是OP想要的。 - Rich Scriven
1
我通常会考虑使用不可变性进行编程。 - bramtayl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接