Новые столбцы из всех возможных комбинаций столбцов фрейма данных - PullRequest
1 голос
/ 08 апреля 2019

Я хочу, чтобы все возможные комбинации были сгруппированы по 2 столбцам в кадре данных без повторений (порядок не имеет значения). Я хочу добавить новый столбец, имеющий имя двух соединяющихся столбцов. Пример:

df
col1  col2 col3 col4 
ind1    a    c    a    
ind2    c    g    a    
ind3    a    g    t         

И я хочу получить:

newdf
col1  col2  col3  col4  col2col3  col2col4  col3col4
ind1    a    c    a         ac       aa        ca 
ind2    c    g    a         cg       ca        ga
ind3    a    g    t         ag       at        gt

Я пробовал следующее:

cl <- c("col2", "col3", "col4") #vector with the columns I want
library(gtools)
lg <- length(cl) 
cmb <- combinations(lg, 2, cl) #this gives me all the combinations without repetition
cmb
     [,1]   [,2]  
[1,] "col2" "col3"
[2,] "col2" "col4"
[3,] "col3" "col4"
cmb <- paste(cmb[,1],cmb[,2]) #for joining the columns of cmb
cmb1 <- paste0("df$",cmb[,1], ", df$", cmb[,2])

После этого я попытался использовать sapply, но я не могу заставить его работать. Это одна из многих попыток.

newdf <- sapply(cmb1, function(x) {
         df$[,x] <- paste0(x)
         })

Есть ли лучший способ сделать это?

1 Ответ

1 голос
/ 08 апреля 2019

Одним из способов является использование mapply() над заранее определенным списком столбцов.Сначала вам нужно создать матрицу имен столбцов, как вы это сделали.Вы также можете использовать comb(), чтобы сделать это:

> df <- data.frame(col2 = c("a", "c", "a"), col3 = c("c", "g", "g"), col4 = c("a", "a", "t"), stringsAsFactors = FALSE)
> nombres <- combn(colnames(df), 2)
> nombres
     [,1]   [,2]   [,3]  
[1,] "col2" "col2" "col3"
[2,] "col3" "col4" "col4"

Затем вы создаете два списка векторов:

> lista1 <- lapply(nombres[1,], function(x){
+   df[,x]
+ })
> 
> lista2 <- lapply(nombres[2,], function(x){
+   df[,x]
+ })
> lista1
[[1]]
[1] "a" "c" "a"

[[2]]
[1] "a" "c" "a"

[[3]]
[1] "c" "g" "g"

> lista2
[[1]]
[1] "c" "g" "g"

[[2]]
[1] "a" "a" "t"

[[3]]
[1] "a" "a" "t"

Наконец, используйте mapply() и paste()два списка:

> mapply(function(x, y){
+   paste(x, y, sep = "")
+ }, x = lista1, y = lista2)
     [,1] [,2] [,3]
[1,] "ac" "aa" "ca"
[2,] "cg" "ca" "ga"
[3,] "ag" "at" "gt"

Тогда вы можете cbind матрицу к исходному фрейму данных:

> df2 <- mapply(function(x, y){
+   paste(x, y, sep = "")
+ }, x = lista1, y = lista2)
> 
> colnames(df2) <- paste(nombres[1,], nombres[2,], sep = "")
> 
> df_new <- cbind.data.frame(df, df2)
> df_new
  col2 col3 col4 col2col3 col2col4 col3col4
1    a    c    a       ac       aa       ca
2    c    g    a       cg       ca       ga
3    a    g    t       ag       at       gt

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...