#r #data.table
#r #data.table
Вопрос:
У меня есть этот код, который выполняет combn для всех значений определенного фрейма данных. Это делается с помощью dplyr rowwise
library(dplyr,warn.conflicts = FALSE)
library(tidyr)
Column1<-c("red","blue")#creating column1
Column2<-c("green","white")#creating column2
Column3<-c("aqua","magenta")#creating column2
df_1<-data.frame(Column1, Column2, Column3)#creating data frame
df_2 <- df_1 %>% rowwise() %>%
mutate(COMB=list(combn(c_across(Column1:Column3),2,simplify = FALSE))) %>%
unnest(cols = COMB) %>%
unnest(cols=COMB)
Создано 2020-11-07 пакетом reprex (версия 0.3.0)
Это приводит к следующему
| # A tibble: 12 x 4 |
|------------------------------------|
| Column1 Column2 Column3 COMB |
| <chr> <chr> <chr> <chr> |
| 1 red green aqua red |
| 2 red green aqua green |
| 3 red green aqua red |
| 4 red green aqua aqua |
| 5 red green aqua green |
| 6 red green aqua aqua |
| 7 blue white magenta blue |
| 8 blue white magenta white |
| 9 blue white magenta blue |
| 10 blue white magenta magenta |
| 11 blue white magenta white |
| 12 blue white magenta magenta |
Возможно ли выполнить функцию rowwise combn в data.table. Например, для следующего
library(data.table)
Column1<-c("red","blue")#creating column1
Column2<-c("green","white")#creating column2
Column3<-c("aqua","magenta")#creating column2
df_1<-data.table(Column1, Column2, Column3)#creating DT
Создано 2020-11-07 пакетом reprex (версия 0.3.0)
Ответ №1:
С data.table
помощью мы можем создать «ГРЕБЕНКУ», используя Map
library(data.table)
setDT(df_1)[, COMB := list(do.call(Map, c(f1, .SD)))]
где
f1 <- function(...) combn(c(...), m = 2, simplify = FALSE)
Или, если мы хотим расширить строки
out <- df_1[, grp := seq_len(.N)][df_1[,
combn(unlist(.SD), 2), .(grp)], on = .(grp)][, grp := NULL]
setnames(out, 'V1', 'COMB')
-вывод
out
# Column1 Column2 Column3 COMB
# 1: red green aqua red
# 2: red green aqua green
# 3: red green aqua red
# 4: red green aqua aqua
# 5: red green aqua green
# 6: red green aqua aqua
# 7: blue white magenta blue
# 8: blue white magenta white
# 9: blue white magenta blue
#10: blue white magenta magenta
#11: blue white magenta white
#12: blue white magenta magenta
Комментарии:
1. Большое спасибо @akrun. «out» был желаемым результатом, который я искал. Это сработало прекрасно. Я новичок в data.table, и у меня есть к вам дополнительный вопрос. Вместо Column1, Column2, Column3 если DT состоял из Column1, Column2, Column3, Column4, Column5, и я хотел передать только Column1, Column4, Column5 как x в combn(x,2), как я могу адаптировать ваше решение
df_1[, grp := seq_len(.N)][df_1[, combn(unlist(.SD), 2), .(grp)], on = .(grp)][, grp := NULL]
к этому?2. Карта AFAIR переносится только в mapply, а с API mapply мне всегда было проще работать.
3. Если в DT присутствуют нежелательные столбцы combn, то адаптируйте решение akrun к тому сценарию
df_1<-data.table(Column1, Column1_1, Column2, Column2_1, Column3) out <- df_1[, grp := seq_len(.N)] out1<-out[df_1[,combn(unlist(.SD), 2), by=.(grp,Column1_1,Column2_1)], on = .(grp,Column1_1,Column2_1)] out1[,!c("Column1_1","Column2_1","grp")]
, когда Column1_1 и Column2_1 нежелательны в combn
Ответ №2:
Вы можете получать данные в длинном формате и создавать комбинации для каждой строки.
library(data.table)
df_1[, row := seq_len(.N)]
df_2 <- melt(df_1, id.vars = 'row')
df_1[df_2[, combn(value, 2), row], on = 'row'][, row := NULL][]
# Column1 Column2 Column3 V1
# 1: red green aqua red
# 2: red green aqua green
# 3: red green aqua red
# 4: red green aqua aqua
# 5: red green aqua green
# 6: red green aqua aqua
# 7: blue white magenta blue
# 8: blue white magenta white
# 9: blue white magenta blue
#10: blue white magenta magenta
#11: blue white magenta white
#12: blue white magenta magenta