将行值拆分为列

时间:2019-02-28 10:34:02

标签: r tidy

我有一些看起来像这样的数据:

samp
# A tibble: 5 x 2
     ID Source        
  <dbl> <chr>         
1 34221 75            
2 33861 75            
3 59741 126,123       
4 56561 111,105       
5 55836 36,34,34,36,22

在任何不同的值中,我想创建一个新列。如果该值连续存在,那么我要估算一个“ x”,否则就不应该估算任何值。

预期结果的示例(伪代码):

ID      75  126 123 111 105 36 34 22         
1 34221 x            
2 33861 x            
3 59741     x   x       
4 56561             x   x    
5 55836                     x  x  x

我通过separtate软件包的tydr函数进行了尝试。像这样开始。

into = unique(unlist(strsplit(samp$Source, ",")))

samp %>% separate(col = "Source", into = into, sep = ",")

但是,这行不通,因为如果一行中有多个值,则不会将这些值分配给相应的列(例如,对于ID 59741,值126位于第75列而不是该列中126)。

 A tibble: 5 x 9
     ID `75`  `126` `123` `111` `105` `36`  `34`  `22` 
  <dbl> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 34221 75    NA    NA    NA    NA    NA    NA    NA   
2 33861 75    NA    NA    NA    NA    NA    NA    NA   
3 59741 126   123   NA    NA    NA    NA    NA    NA   
4 56561 111   105   NA    NA    NA    NA    NA    NA   
5 55836 36    34    34    36    22    NA    NA    NA  

这里是dput

structure(list(ID = c(34221, 33861, 59741, 56561, 55836), Source = c("75", 
"75", "126,123", "111,105", "36,34,34,36,22")), row.names = c(NA, 
-5L), class = c("tbl_df", "tbl", "data.frame"))

3 个答案:

答案 0 :(得分:2)

splitstackshape包对于此类操作非常方便,即

library(splitstackshape)

cSplit_e(df, "Source", mode = "binary", type = "character", fill = 0, drop = TRUE)

给出,

     ID Source_105 Source_111 Source_123 Source_126 Source_22 Source_34 Source_36 Source_75
1 34221          0          0          0          0         0         0         0         1
2 33861          0          0          0          0         0         0         0         1
3 59741          0          0          1          1         0         0         0         0
4 56561          1          1          0          0         0         0         0         0
5 55836          0          0          0          0         1         1         1         0

答案 1 :(得分:2)

还可以:

library(tidyverse)

df %>%
  mutate(Source = strsplit(Source, ","),
         dummy = "x") %>% 
  unnest() %>% distinct() %>%
  spread(Source, dummy)

输出:

     ID `105` `111` `123` `126` `22`  `34`  `36`  `75` 
  <dbl> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 33861 NA    NA    NA    NA    NA    NA    NA    x    
2 34221 NA    NA    NA    NA    NA    NA    NA    x    
3 55836 NA    NA    NA    NA    x     x     x     NA   
4 56561 x     x     NA    NA    NA    NA    NA    NA   
5 59741 NA    NA    x     x     NA    NA    NA    NA   

答案 2 :(得分:2)

另一个选择是使用tidyr::separate_rows

library(dplyr)
library(tidyr)
df %>% separate_rows(Source,sep=',') %>% distinct() %>% 
       mutate(dummy='X') %>% spread(Source,dummy)

     ID  105  111  123  126   22   34   36   75
1 33861 <NA> <NA> <NA> <NA> <NA> <NA> <NA>    X
2 34221 <NA> <NA> <NA> <NA> <NA> <NA> <NA>    X
3 55836 <NA> <NA> <NA> <NA>    X    X    X <NA>
4 56561    X    X <NA> <NA> <NA> <NA> <NA> <NA>
5 59741 <NA> <NA>    X    X <NA> <NA> <NA> <NA>