Вычисление комбинаций имен столбцов без дубликатов с помощью combn

У меня есть два фрейма данных с 3 столбцами каждый, и каждый фрейм данных состоит из разных типов данных (df1 имеет непрерывные данные с суффиксом имени столбца «con», df2 имеет категориальные данные с суффиксом имени столбца «cat»)

Мои данные:

df1 <- data.frame(t1_con=c(1:5), t2_con=c(6:10), t3_con=c(11:15))
df2 <- data.frame(t1_cat=letters[1:5], t2_cat=letters[6:10], t3_cat=letters[11:15]))

Я хотел бы получить все комбинации имен столбцов, то есть t1_con, t2_con, t3_cat. Я пробовал этот код:

df3 <- cbind(df1, df2)
results <- combn(names(df3),3,simplify=FALSE)
trait_combinations <- melt(results)

Это дает мне такие комбинации, как: t1_con, t2_con, t1_cat, у которого есть дубликат t1. Но мне не нужны дубликаты t1, t2 или t3. Например. группа 1 хороша, поскольку в группе есть t1, t2 и t3, но у группы 2 есть дубликат t1:

head(trait_combinations)

value L1
1 t1_con  1
2 t2_con  1
3 t3_con  1
4 t1_con  2
5 t2_con  2
6 t1_cat  2

Есть ли способ предотвратить появление дубликатов в combn или удалить дублированные строки постфактум? Я мог бы удалить суффиксы, но мне нужно знать, какие столбцы являются непрерывными и категориальными, для дальнейшего анализа.

Спасибо за вашу помощь.


person LHordley    schedule 02.04.2020    source источник
comment
Ну, ленивым и неэффективным способом было бы сгенерировать все комбинации, а затем использовать функцию unique   -  person James Curran    schedule 02.04.2020
comment
Уникальный не работает, когда у меня есть суффиксы в именах столбцов. Но если я их сниму, это произойдет. У меня сложился сложный способ получить то, что я хочу, но в идеале есть более быстрый способ (так как это будет повторяться 1000 раз).   -  person LHordley    schedule 02.04.2020
comment
Это код: trait_combinations2 <- trait_combinations trait_combinations2$value <- sub("_[^_]+$", "", trait_combinations2$value) ## keep first values trait_combinations2 <- unique(trait_combinations2) trait_combinations2 <- trait_combinations2 %>% group_by(L1) %>% filter(n() >= ncol(trait_temp2)) trait_combinations2 <- trait_combinations2[,-1] trait_combinations3 <- match_df(trait_combinations, trait_combinations2, on = NULL)   -  person LHordley    schedule 02.04.2020
comment
Я согласен, что это неэффективно (это то, что я сказал :-)), но я озадачен, почему это не работает. У меня это отлично работает > unique(c("t1_con", "t1_con", "t1_cat")) [1] "t1_con" "t1_cat"   -  person James Curran    schedule 02.04.2020


Ответы (2)


Вы можете попробовать

do.call(expand.grid,
        data.frame(rbind(names(df1),names(df2))))

который дает

      X1     X2     X3
1 t1_con t2_con t3_con
2 t1_cat t2_con t3_con
3 t1_con t2_cat t3_con
4 t1_cat t2_cat t3_con
5 t1_con t2_con t3_cat
6 t1_cat t2_con t3_cat
7 t1_con t2_cat t3_cat
8 t1_cat t2_cat t3_cat
person ThomasIsCoding    schedule 02.04.2020

Вы можете использовать expand.grid() для создания всех 8 комбинаций.

expand.grid(Map(c, names(df1), names(df2), USE.NAMES = F))

#     Var1   Var2   Var3
# 1 t1_con t2_con t3_con
# 2 t1_cat t2_con t3_con
# 3 t1_con t2_cat t3_con
# 4 t1_cat t2_cat t3_con
# 5 t1_con t2_con t3_cat
# 6 t1_cat t2_con t3_cat
# 7 t1_con t2_cat t3_cat
# 8 t1_cat t2_cat t3_cat

Описание

Сначала используйте Map, чтобы создать список с указанием 3 групп переменных-кандидатов:

Map(c, names(df1), names(df2), USE.NAMES = F)

[[1]]
[1] "t1_con" "t1_cat"

[[2]]
[1] "t2_con" "t2_cat"

[[3]]
[1] "t3_con" "t3_cat"

Затем expand.grid() выберет по одной переменной из каждой группы и, следовательно, сгенерирует все 8 комбинаций.

person Darren Tsai    schedule 02.04.2020