Как перенести столбцы вместе, а затем отсортировать их в R

#r

#r

Вопрос:

У меня есть 20 столбцов, и вот часть примера для предоставления данных:

 df <- read.table(text = "Id1    Id2 Id3 Id4 Id5 Id6 Id7 Id8
Ali.J   koli.M  Handy.M kori.Z  Simon.B James.K Moli.Z  kori.Z
Smith.kol   Hoddy.G Nancy.M kori.Z  Simon.B Khan.M  Moli.Z  Peter.K
Kato.Bada   Ahadi.M Nancy.M kori.Z  Simon.B Khan.M  Moli.Z  Peter.K
Moli.Z  Rosi.Bab    Handy.M Khan.M  Rose.M  Khan.M  Ali.J   Peter.K
Nadia.M Ali.J   Kato.Bada   Khan.M  Rose.M  Khan.M  Ali.J   Peter.K
Sarah.B Moli.z  Handy.M Khan.M  Rose.M  James.K Ali.J   Kato.Bada
 ", header = TRUE)  

Как вы можете видеть, у меня 8 идентификаторов. Я хочу переместить идентификаторы, как вы можете видеть ниже. Например, Ali.j отображается в id1, id2 и id7. Итак, в первом столбце мы видим id1, id2 и id7. второй столбец — это имя, а последний столбец — частота, основанная на столбце 1, так что это три раза, наконец, я хочу получить сумму для второго и третьего столбцов. Вот предполагаемый результат.

 ID  Name    freq
id1,id2,id7 Ali.J   3
id1 Smith.Kol   1
id1,id3,id8 Kato.Bada   3
id1,id2,id7 Moli.Z  3
id1 Nadia.M 1
id1 Sarah.B 1
id2 Koli.M  1
id2 Hoddy.G 1
id2 Ahadi.M 1
id2 Rosi.Bab    1
id3 Handy.M 1
id3 Nancy.M 1
id4,id8 Kori.Z  1
id4,id6 Khan.M  1
id5 Simon.B 1
id5 Rose.M  1
id6 James.K 1
id8 Peter.k 1
sum 18  24  

Можем ли мы сделать это в R?

Ответ №1:

Мы можем использовать aggregate из base R

 aggregate(ind ~ ., unique(stack(df)), FUN = function(x) 
           c(N = length(x), Var = toString(x)))
  

-вывод

 #      values ind.N       ind.Var
#1    Ahadi.M     1           Id2
#2      Ali.J     3 Id1, Id2, Id7
#3    Handy.M     1           Id3
#4    Hoddy.G     1           Id2
#5    James.K     1           Id6
#6  Kato.Bada     3 Id1, Id3, Id8
#7     Khan.M     2      Id4, Id6
#8     koli.M     1           Id2
#9     kori.Z     2      Id4, Id8
#10    Moli.z     1           Id2
#11    Moli.Z     2      Id1, Id7
#12   Nadia.M     1           Id1
#13   Nancy.M     1           Id3
#14   Peter.K     1           Id8
#15    Rose.M     1           Id5
#16  Rosi.Bab     1           Id2
#17   Sarah.B     1           Id1
#18   Simon.B     1           Id5
#19 Smith.kol     1           Id1
  

Ответ №2:

Попробуйте этот tidyverse подход:

 library(dplyr)
library(tidyr)
#Code
newdf <- df %>% pivot_longer(everything()) %>%
  group_by(value) %>% summarise(N=n_distinct(name),
                                Var=toString(unique(name)))
  

Вывод:

 # A tibble: 19 x 3
   value         N Var          
   <fct>     <int> <chr>        
 1 Ali.J         3 Id1, Id7, Id2
 2 Kato.Bada     3 Id1, Id3, Id8
 3 Moli.Z        2 Id7, Id1     
 4 Nadia.M       1 Id1          
 5 Sarah.B       1 Id1          
 6 Smith.kol     1 Id1          
 7 Ahadi.M       1 Id2          
 8 Hoddy.G       1 Id2          
 9 koli.M        1 Id2          
10 Moli.z        1 Id2          
11 Rosi.Bab      1 Id2          
12 Handy.M       1 Id3          
13 Nancy.M       1 Id3          
14 Khan.M        2 Id6, Id4     
15 kori.Z        2 Id4, Id8     
16 Rose.M        1 Id5          
17 Simon.B       1 Id5          
18 James.K       1 Id6          
19 Peter.K       1 Id8   
  

Комментарии:

1. Это решение лучше моего, потому что оно улавливает необходимость подсчета уникальных значений.

2. Пожалуйста, посмотрите мой вывод. можем ли мы сделать лучше?

Ответ №3:

Используя только цикл (но, вероятно, лучше узнать, как использовать пакеты из других ответов):

 newdf = data.frame(names = unique(as.vector(as.matrix(df))))
for(i in 1:nrow(newdf)){
  index = which(apply(df,2,function(x){newdf$names[i] %in% x}))
  newdf$id[i] = paste(names(index), collapse=", ")
  newdf$frequency[i] = length(index)}
  

Ответ №4:

Вот tidyverse решение. pivot_longer() Функция from tidyr берет вашу таблицу и превращает ее в длинный data.frame с каждой строкой в паре Имя-идентификатор. Если group_by(Name) мы можем summarise() разделить данные по группам. n() Функция подсчитывает строки и toString() преобразует вектор в строку из одного символа, разделенную запятыми.

 library(dplyr)
library(tidyr)

df %>%
  pivot_longer(everything(), names_to = "ID", values_to = "Name") %>%
  group_by(Name) %>%
  summarise(freq = n(),
            ID = toString(ID))
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 19 x 3
   Name       freq ID                               
   <chr>     <int> <chr>                            
 1 Ahadi.M       1 Id2                              
 2 Ali.J         5 Id1, Id7, Id2, Id7, Id7          
 3 Handy.M       3 Id3, Id3, Id3                    
 4 Hoddy.G       1 Id2                              
 5 James.K       2 Id6, Id6                         
 6 Kato.Bada     3 Id1, Id3, Id8                    
 7 Khan.M        7 Id6, Id6, Id4, Id6, Id4, Id6, Id4
 8 koli.M        1 Id2                              
 9 kori.Z        4 Id4, Id8, Id4, Id4               
10 Moli.z        1 Id2                              
11 Moli.Z        4 Id7, Id7, Id7, Id1               
12 Nadia.M       1 Id1                              
13 Nancy.M       2 Id3, Id3                         
14 Peter.K       4 Id8, Id8, Id8, Id8               
15 Rose.M        3 Id5, Id5, Id5                    
16 Rosi.Bab      1 Id2                              
17 Sarah.B       1 Id1                              
18 Simon.B       3 Id5, Id5, Id5                    
19 Smith.kol     1 Id1  
  

Комментарии:

1. Спасибо, но это не отражает мой результат, а также пошло не так, плюс ошибка: неожиданный символ в » summarise() разгруппировке»