将行值拆分为列

问题描述 投票:0回答:3

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

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"))
r tidy
3个回答
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
投票

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

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>
© www.soinside.com 2019 - 2024. All rights reserved.