在R中基于三个其他列的值创建新列

3

I have a dataframe:

df <- data.frame('a'=c(1,NA,3,NA,NA), 'b'=c(NA,NA,NA,4,50), 'c'=c(NA,5,NA,NA,NA))
df
   a  b  c
1  1 NA NA
2 NA NA  5
3  3 NA NA
4 NA  4 NA
5 NA 50 NA

我需要创建一个新列d,将仅包含非NA值的值组合起来:
  a  b  c  d
1  1 NA NA 1
2 NA NA  5 5
3  3 NA NA 3
4 NA  4 NA 4
5 NA 50 NA 50

3
rowSums(df, na.rm=TRUE),或者如果它总是1,你不想冒险求和,则可以使用apply(df[1:3], 1, na.omit)apply(df[1:3], 1, function(z) na.omit(z)[1]) - r2evans
4个回答

4

除了评论区中@r2evans提出的解决方案外,我们还可以使用dplyr包中的coalesce函数:

df %>% 
  mutate(d = coalesce(a, b, c))

   a  b  c  d
1  1 NA NA  1
2 NA NA  5  5
3  3 NA NA  3
4 NA  4 NA  4
5 NA 50 NA 50

我们可以使用 tidyr 包中的 unite 函数,并加上 na.rm 参数:

library(tidyr)
library(dplyr)

df %>% 
  unite(d, a:c, na.rm = TRUE, remove = FALSE)

   d  a  b  c
1  1  1 NA NA
2  5 NA NA  5
3  3  3 NA NA
4  4 NA  4 NA
5 50 NA 50 NA

1
您可以不使用任何库,简单地执行以下操作:
df$d <- apply(df, MARGIN=1, function(x) x[!is.na(x)])

   a  b  c  d
1  1 NA NA  1
2 NA NA  5  5
3  3 NA NA  3
4 NA  4 NA  4
5 NA 50 NA 50

它的工作原理如下: 将一个向量作为输入,返回其中的非na元素的函数function(x) x[!is.na(x)]被应用于每一行(margin=1)。

1
base R 中的矢量化选项是使用 max.col 来获取非 NA 值的列索引,使用行序列和提取元素的 cbind
df$d <- df[cbind(seq_len(nrow(df)), max.col(!is.na(df)))]

-输出

> df
   a  b  c  d
1  1 NA NA  1
2 NA NA  5  5
3  3 NA NA  3
4 NA  4 NA  4
5 NA 50 NA 50

1
另一个选择是使用 data.table 中的 fcoalesce,它接受一个数据框并允许您省略添加列名的步骤。
library(data.table)

df$d <- fcoalesce(df)

输出

   a  b  c  d
1  1 NA NA  1
2 NA NA  5  5
3  3 NA NA  3
4 NA  4 NA  4
5 NA 50 NA 50

或者我们可以使用do.callpmax

df$d <- do.call(pmax, c(df, list(na.rm=TRUE)))

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