r - 合并列并创建另一列以指定源

标签 r dataframe dplyr

我正在使用 dplyr::coalesce()将几列合并为一列。最初,跨列,每行只有一列具有实际值,而其他列是 NA .基于合并,我想创建一个附加列,该列将指定从中获取合并值的源列。
我的尝试受到其他 dplyr 中现有功能的启发职能。例如,dplyr::bind_rows().id为新数据帧中的每一行指定源数据帧的参数。
来自 bind_rows()的文档:

When .id is supplied, a new column of identifiers is created to link each row to its original data frame. The labels are taken from the named arguments to bind_rows(). When a list of data frames is supplied, the labels are taken from the names of the list. If no names are found a numeric sequence is used instead.


同样,我目前的问题是关于 coalesce() ,不是 bind_rows() ,但我只是想把它放在上下文中。
数据
df <-
  data.frame(
  group_1 = c(NA, NA, NA, NA, 2),
  group_2 = c(NA, 4, NA, NA, NA),
  group_3 = c(NA, NA, 5, NA, NA),
  group_4 = c(1, NA, NA, 2, NA),
  group_5 = c(NA, NA, NA, NA, NA)
)

df

##   group_1 group_2 group_3 group_4 group_5         ## each row
## 1      NA      NA      NA       1      NA         ## has one value
## 2      NA       4      NA      NA      NA         ## and the rest
## 3      NA      NA       5      NA      NA         ## are NAs
## 4      NA      NA      NA       2      NA
## 5       2      NA      NA      NA      NA
将列合并为一个(附加)列
library(dplyr)

df %>%
  mutate(one_col = coalesce(group_1, group_2, group_3, group_4, group_5))

##   group_1 group_2 group_3 group_4 group_5 one_col
## 1      NA      NA      NA       1      NA       1
## 2      NA       4      NA      NA      NA       4
## 3      NA      NA       5      NA      NA       5
## 4      NA      NA      NA       2      NA       2
## 5       2      NA      NA      NA      NA       2
如何添加另一列来指定“源”,即 one_col 中的值来自哪一列是从?
期望输出
  group_1 group_2 group_3 group_4 group_5 one_col source_col
1      NA      NA      NA       1      NA       1    group_4
2      NA       4      NA      NA      NA       4    group_2
3      NA      NA       5      NA      NA       5    group_3
4      NA      NA      NA       2      NA       2    group_4
5       2      NA      NA      NA      NA       2    group_1

编辑

下面@Karthik 的回答让我认为我上面使用的示例数据展示了一种过于狭隘和具体的情况。 Karthik 提供的解决方案独立于聚结操作。因此,如果我们交换订单并创建 source_col,代码仍然可以工作。首先也是唯一coalesce .
但是,如果数据有多个 NA每行,coalesce仍然会做它的事情,但我们不能再基于 source_col在找到单个非缺失值时。因此,我正在修改问题和数据。
数据
df_2 <-
  data.frame(
  group_1 = c(NA, NA, NA, NA, 2),
  group_2 = c(NA, 4, NA, NA, 1),
  group_3 = c(NA, NA, 5, NA, NA),
  group_4 = c(1, NA, NA, 2, NA),
  group_5 = c(NA, 3, NA, NA, NA)
)

> df_2

##   group_1 group_2 group_3 group_4 group_5
## 1      NA      NA      NA       1      NA   ## <--- one non-NA
## 2      NA       4      NA      NA       3   ## <--- *two* non-NA
## 3      NA      NA       5      NA      NA   ## <--- one non-NA
## 4      NA      NA      NA       2      NA   ## <--- one non-NA
## 5       2       1      NA      NA      NA   ## <--- *two* non-NA
聚结
> df_2 %>%
   mutate(one_col = coalesce(group_1, group_2, group_3, group_4, group_5))

##   group_1 group_2 group_3 group_4 group_5 one_col
## 1      NA      NA      NA       1      NA       1
## 2      NA       4      NA      NA       3       4
## 3      NA      NA       5      NA      NA       5
## 4      NA      NA      NA       2      NA       2
## 5       2       1      NA      NA      NA       2
如何添加与 coalesce() 选择的值匹配的源列它来自原始列?
期望输出
  group_1 group_2 group_3 group_4 group_5 one_col source_col
1      NA      NA      NA       1      NA       1    group_4
2      NA       4      NA      NA       3       4    group_2
3      NA      NA       5      NA      NA       5    group_3
4      NA      NA      NA       2      NA       2    group_4
5       2       1      NA      NA      NA       2    group_1

最佳答案

这是否有效:

df %>%
   mutate(one_col = coalesce(group_1, group_2, group_3, group_4, group_5)) %>% 
rowwise() %>% mutate(group_col = names(df)[!is.na(c_across(group_1:group_5))])
# A tibble: 5 x 7
# Rowwise: 
  group_1 group_2 group_3 group_4 group_5 one_col group_col
    <dbl>   <dbl>   <dbl>   <dbl> <lgl>     <dbl> <chr>    
1      NA      NA      NA       1 NA            1 group_4  
2      NA       4      NA      NA NA            4 group_2  
3      NA      NA       5      NA NA            5 group_3  
4      NA      NA      NA       2 NA            2 group_4  
5       2      NA      NA      NA NA            2 group_1  
>
更新答案:
df_2 %>% mutate(one_col = coalesce(group_1, group_2, group_3, group_4, group_5)) %>% rowwise() %>% 
   mutate(group_col = names(df_2)[!is.na(c_across(group_1:group_5))][1])
# A tibble: 5 x 7
# Rowwise: 
  group_1 group_2 group_3 group_4 group_5 one_col group_col
    <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl> <chr>    
1      NA      NA      NA       1      NA       1 group_4  
2      NA       4      NA      NA       3       4 group_2  
3      NA      NA       5      NA      NA       5 group_3  
4      NA      NA      NA       2      NA       2 group_4  
5       2       1      NA      NA      NA       2 group_1  

关于r - 合并列并创建另一列以指定源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64755673/

相关文章:

r - 如何使用R将每小时乘客OD数据传输到od矩阵

r - 如何在申请家庭内分配?

javascript - Shiny未检测到shiny :inputchanged event

r - Fisher 在 R 中根据数据帧进行精确测试

python-3.x - Spark 中的 Parquet 字节数据帧转换为 UTF-8

r - 应用 cumsum 时 dplyr 不尊重 group_by

r - 传播多列 [tidyr]

r - 使用R/python依赖项优化Docker

r - 如何从 2 个向量创建单行 data.frame (tibble)。一个具有所需的列名,另一个具有该行的值?

将 NA 替换为另一列的最大因子数