R 合并列并创建另一列以指定源
我正在使用R 合并列并创建另一列以指定源,r,dataframe,dplyr,R,Dataframe,Dplyr,我正在使用dplyr::coalesce()将多个列合并为一个列。最初,跨列,每行只有一列具有实际值,而其他列为NA。基于合并,我想创建一个附加列,该列将指定从中获取合并值的源列 我的尝试受到其他dplyr函数中现有功能的启发。例如,dplyr::bind_rows()具有指定新数据帧中每一行的源数据帧的.id参数 从bind_rows()的文档: 当提供.id时,将创建一列新的标识符来链接 将每一行复制到其原始数据帧。标签取自 绑定_行()的命名参数。当显示数据帧列表时 提供的标签取自列表的名
dplyr::coalesce()
将多个列合并为一个列。最初,跨列,每行只有一列具有实际值,而其他列为NA
。基于合并,我想创建一个附加列,该列将指定从中获取合并值的源列
我的尝试受到其他dplyr
函数中现有功能的启发。例如,dplyr::bind_rows()
具有指定新数据帧中每一行的源数据帧的.id
参数
从bind_rows()
的文档:
当提供.id时,将创建一列新的标识符来链接
将每一行复制到其原始数据帧。标签取自
绑定_行()的命名参数。当显示数据帧列表时
提供的标签取自列表的名称。如果没有名字
如果找到,则使用数字序列
同样,我当前的问题是关于coalesce()
,而不是bind_rows()
,但我只是想把它放在上下文中
资料
df%
突变(一列=结合(第1组、第2组、第3组、第4组、第5组))
##第1组第2组第3组第4组第5组第1列
##1NA NA 1NA 1
##2钠4钠4钠
##3钠5钠5钠
##4NaNa2Na2
##5.2纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳纳
我如何添加另一列来指定“源”,即
one\u col
中的值是从哪个列获取的?
期望输出
group_1 group_2 group_3 group_4 group_5 one_col source_col
1 NA NA 1 NA 1组4
2 NA 4 NA 4组2
3-NA-NA-5-NA-5组_3
4 NA NA 2 NA 2组4
5 2 NA 2组\u 1
编辑
@Karthik下面的回答让我想到,我上面使用的示例数据说明了一种过于狭窄和具体的情况。Karthik提供的解决方案独立于聚结操作。因此,如果我们交换顺序,先创建
源列,然后再创建合并,代码仍然可以工作
但是,如果数据每行有一个以上的NA
,coalesce
仍会这样做,但我们不能再将source\u col
建立在查找单个非缺失值的基础上。因此,我正在修改问题和数据
资料
df_2 df_2
##第1组第2组第3组第4组第5组
##1NA NA 1NA##这是否有效:
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%>%
突变(一列=结合(第1组、第2组、第3组、第4组、第5组))%>%
行()
#一个tibble:5x7
#顺时针:
组1组2组3组4组5一列组
1 NA NA 1 NA 1组4
2 NA 4 NA 4组2
3-NA-NA-5-NA-5组_3
4 NA NA 2 NA 2组4
5 2 NA 2组\u 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
df_2%>%突变(一列=合并(组_1、组_2、组_3、组_4、组_5))%>%rowwise()%>%
变异(group_col=names(df_2)[!is.na(c_cross(group_1:group_5))][1])
#一个tibble:5x7
#顺时针:
组1组2组3组4组5一列组
1 NA NA 1 NA 1组4
2 NA 4 NA 3 4组2
3-NA-NA-5-NA-5组_3
4 NA NA 2 NA 2组4
5 2 1 NA 2组1
这似乎正在将数据从宽格式改为长格式
df2 <- reshape(df,
direction = 'long',
varying = 1:5,
v.names = 'one_col',
timevar = 'source_col',
times = paste0('group_', 1:5))
以下是一个快速基本解决方案:
cbind(df_2,
t(apply(df_2, 1, function(i){
c(i[ which(!is.na(i))[1] ],
colnames(df_2)[ which(!is.na(i))[1] ])
}))
)
# group_1 group_2 group_3 group_4 group_5 1 2
# 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
可以肯定的是,这可以通过使用“which.min/is.na/arrayInd”组合来完成,而无需应用循环,目前没有时间进行测试。谢谢,@Karthik。根据我输入的数据,您的解决方案可以完成工作。然而,这不是我在发表这个问题时的想法。我编辑了这篇文章来澄清这一点。@Emman,我已经更新了我的答案,请检查这是否适用于你。
cbind(df_2,
t(apply(df_2, 1, function(i){
c(i[ which(!is.na(i))[1] ],
colnames(df_2)[ which(!is.na(i))[1] ])
}))
)
# group_1 group_2 group_3 group_4 group_5 1 2
# 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