首页 > 解决方案 > 如何基于 R 中所有现有列的成对组合创建新列?

问题描述

我有一个包含约 6000 列的数据框。每列都包含一个国家名称,该名称代表图表中的一个节点。一行内的国家通过边缘连接。

这看起来像这样:

df <- data.frame(ID = c(1,2,3), 
                  Country_1 = c("Germany", "Russia", "Germany"),
                  Country_2 = c(NA, "Germany", NA),
                  Country_n = c("China", "China", "China"))
ID Country_1 Country_2 ... Country_n 
1  Germany   NA        ... China     
2  Russia    Germany   ... China     
3  Germany   NA        ... China     
.
.
.

期望的结果

我想创建包含国家之间互动的新列。NA应该被忽略。

ID  Ctr_Int_1       Ctr_Int_2    ...   Ctr_Int_n 
1  Germany-China        NA       ...      NA
2  Russia-Germany   Russia-China ...  Germany-China   
3  Germany-China        NA       ...      NA  
.
.
.

代码

我可以一步一步地做到这一点[1]但 NA 不会被忽略,并且随着列数的增加它不再可行。

library(tidyr)
library(dplyr)

# step by step
df <- df %>% unite(CountryInt_1, Country_1, Country_2, sep = "-", remove = FALSE)
df <- df %>% unite(CountryInt_2, Country_1, Country_n, sep = "-", remove = FALSE)
df <- df %>% unite(CountryInt_3, Country_2, Country_n, sep = "-", remove = FALSE)

# remove additional columns
country_names <- paste0("Country_", 1:3)

`%ni%` <- Negate(`%in%`)
df <- subset(df,select = names(df) %ni% country_names)
ID  Ctr_Int_1       Ctr_Int_2     ...    Ctr_Int_n 
1  Germany-China    Germany-NA    ...    China-NA
2  Russia-Germany   Russia-China  ...    Germany-China   
3  Germany-NA       Germany-China ...    China-NA  
.
.
.

我认为必须有解决这个问题或类似问题的方法,因为它不应该是闻所未闻的,但我找不到它。我想应该有一种方法使用base::apply和/或类似于这里所做的事情[2和这里3] - 但我不太熟悉data.table并且无法实现它。

如果有人能指出我正确的方向,那肯定会有所帮助。

编辑:感谢@NotThatKindOdr,NAs 的问题得到了解决,但是,更紧迫的问题仍然存在,因为每次手动创建 Country-to-Country 组合是不可行的。

标签: rdataframedplyrdata.tabletidyr

解决方案


使用的选项data.table

library(data.table)
dcast(
    melt(setDT(df), id.vars="ID", na.rm=TRUE)[, 
        combn(value, 2L, function(x) paste(x, collapse="-")), ID][,
            ri := paste0("Ctr_Int_", rowid(ID))],
    ID ~ ri, value.var="V1")

输出:

   ID      Ctr_Int_1    Ctr_Int_2     Ctr_Int_3
1:  1  Germany-China         <NA>          <NA>
2:  2 Russia-Germany Russia-China Germany-China
3:  3  Germany-China         <NA>          <NA>

推荐阅读