根据相似的列将行中的值分组

时间:2019-10-27 22:01:29

标签: r dataframe

我有一列里面有多个值。 喜欢...

ColumnX1
A,D,C,B,F,E,G
F,A,B,E,G,C
C,D,G,F,A,T

我用分割数据

Species_Data2 <- data.frame(str_split_fixed(Species_Data$Other.Anopheline.species, ",", 21))

但是我得到的值如下:

我的数据框如下:-

X1    X2    X3      X4        X5        X6      X7
A     D     C       B         F         E       G
F     A     B       E         G         NA      C
C     D     G       F         A         T      NA

我想制作一个像这样的数据框:

X1    X2    X3      X4        X5        X6      X7    X8
A     B     C       D         E         F       G     NA
A     B     C       NA        E         F       G     NA
A     NA    C       D         NA        F       G     T

然后... 我想将列名称作为行值:-

姓氏

'A'    'B'   'C'     'D'       'E'       'F'     'G'    'T' 
  A     B     C        D         E         F       G     NA
  A     B     C       NA         E         F       G     NA
  A    NA     C        D        NA         F       G      T

试图创建排序...但效果不佳...:(..

Comes up with O values though....

1 个答案:

答案 0 :(得分:0)

如果我理解正确,则OP希望重新排列数据,以便每个字母都有单独的列。如果一行中存在一个字母,则该字母将出现在整形数据的适当列/行中。 NA表示连续缺少一个字母。另外,字母列应按字母顺序排列。

1。 dplyr / tidyr方法

如果我们从OP调用stringr::str_split_fixed()产生的data.frame开始,我们需要将分割后的数据从宽格式整形为长格式,删除空条目,对行进行排序,以使列以字母顺序显示并整形为大幅面格式。要整形,需要一个行ID。为了获得所需的输出,必须将pivot_wide()参数称为names_from = value

library(dplyr)
library(tidyr)
as.data.frame(stringr::str_split_fixed(DF$ColumnX1, ",", 21)) %>% 
  mutate(rn = row_number()) %>% 
  pivot_longer(-rn) %>% 
  filter(value != "") %>% 
  arrange(as.character(value)) %>% 
  pivot_wider(rn, names_from = value) 
     rn A     B     C     D     E     F     G     T    
  <int> <fct> <fct> <fct> <fct> <fct> <fct> <fct> <fct>
1     1 A     B     C     D     E     F     G     NA   
2     2 A     B     C     NA    E     F     G     NA   
3     3 A     NA    C     D     NA    F     G     T

2。 data.table方法

如果我们从未分割的原始数据开始,则有一个更简洁的变体,它使用data.table的{​​{1}}进行重塑:

dcast()
library(data.table)
setDT(DF)[, stringr::str_split(ColumnX1, ","), by = 1:nrow(DF)][, dcast(.SD, nrow ~ V1)]

如果需要,可以在两种方法中都删除附加的行ID列。

数据

   nrow A    B C    D    E F G    T
1:    1 A    B C    D    E F G <NA>
2:    2 A    B C <NA>    E F G <NA>
3:    3 A <NA> C    D <NA> F G    T

编辑:重复的值

In a comment,OP披露生产数据集包含重复值。

在值重复的情况下,DF <- data.frame(ColumnX1 = c("A,D,C,B,F,E,G", "F,A,B,E,G,C", "C,D,G,F,A,T") ) 默认使用dcast()函数来聚合数据。

如果修改后的数据集length()在第1行和第2行中包含重复的值,则原始的DF2方法将返回:

data.table
library(data.table)
setDT(DF2)[, stringr::str_split(ColumnX1, ","), by = 1:nrow(DF)][, dcast(.SD, nrow ~ V1)]

在这里,显示重复字母的数量。

在使用 nrow A B C D E F G T 1: 1 1 1 2 1 1 1 1 0 2: 2 1 1 1 0 1 2 1 0 3: 3 1 0 1 1 0 1 1 1 进行重塑之前,可以通过删除重复的值来恢复预期的行为:

unique()
setDT(DF2)[, stringr::str_split(ColumnX1, ","), by = 1:nrow(DF)][
  , dcast(unique(.SD), nrow ~ V1)]

还需要通过在对 nrow A B C D E F G T 1: 1 A B C D E F G <NA> 2: 2 A B C <NA> E F G <NA> 3: 3 A <NA> C D <NA> F G T 的调用中指定适当的聚合函数来修改dplyr / tidyr方法:

pivot_wider()

具有重复值的数据

library(dplyr)
library(tidyr)
as.data.frame(stringr::str_split_fixed(DF2$ColumnX1, ",", 21)) %>% 
  mutate(rn = row_number()) %>% 
  pivot_longer(-rn) %>% 
  filter(value != "") %>% 
  arrange(as.character(value)) %>% 
  pivot_wider(rn, names_from = value, values_fn = list(value = unique))