根据唯一值将单个列分隔为多个

时间:2017-09-18 22:27:18

标签: r dplyr tidyr data-cleaning tidy

假设您有一个类似于此的数据表

我为糟糕的格式道歉

name  time  code val
cat   2012  a2   2321
dog   1980  b2   424
cat   2101  c6   34
moose 2310  c6   5.6
dog   1972  h9   34
lion  1982  g8   12

我想让它获取所有唯一代码,以便表格像这样排列

name  time  a2   b2   c6   h9   g8
cat   2012  2321 NA   NA   NA   NA
dog   1980  NA   424  NA   NA   NA
cat   2101  NA   NA   34   NA   NA
moose 2310  NA   NA   5.6  NA   NA
dog   1972  NA   NA   NA   34   NA
lion  1982  NA   NA   NA   NA   12

有人可以描述我将如何在R中这样做吗?您不必提供任何代码,但有关如何执行此操作的一些指示将是很好的。我使用的数据集要大得多,可能包含许多副本。

感谢任何建议

感谢您阅读

2 个答案:

答案 0 :(得分:1)

reshape2使这些转换变得非常简单。

require(reshape2)

df1 <- structure(list(name = structure(c(1L, 2L, 1L, 4L, 2L, 3L), .Label = c("cat", 
"dog", "lion", "moose"), class = "factor"), time = c(2012L, 1980L, 
2101L, 2310L, 1972L, 1982L), code = structure(c(1L, 2L, 3L, 3L, 
5L, 4L), .Label = c("a2", "b2", "c6", "g8", "h9"), class = "factor"), 
    val = c(2321, 424, 34, 5.6, 34, 12)), .Names = c("name", 
"time", "code", "val"), class = "data.frame", row.names = c(NA, 
-6L))

dcast(df1, name + time ~ code, value.var="val")

   name time   a2  b2   c6 g8 h9
1   cat 2012 2321  NA   NA NA NA
2   cat 2101   NA  NA 34.0 NA NA
3   dog 1972   NA  NA   NA NA 34
4   dog 1980   NA 424   NA NA NA
5  lion 1982   NA  NA   NA 12 NA
6 moose 2310   NA  NA  5.6 NA NA

或与tidyr::spread类似。 tidyr使用格式spread(data, <column name whose values will be used as headings>, values)

更直观一些
spread(df1,code,val)

答案 1 :(得分:1)

我正在为@ {Mako212已经提到的spread添加工作示例:

library(tidyverse)

df <- tribble(
~name,  ~time,  ~code, ~val,
"cat",   2012,  "a2",   2321,
"dog",   1980,  "b2",   424,
"cat",   2101,  "c6",   34,
"moose", 2310,  "c6",   5.6,
"dog",   1972,  "h9",   34,
"lion",  1982,  "g8",   12)

df %>% spread(code, val)
#> # A tibble: 6 x 7
#>    name  time    a2    b2    c6    g8    h9
#> * <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1   cat  2012  2321    NA    NA    NA    NA
#> 2   cat  2101    NA    NA  34.0    NA    NA
#> 3   dog  1972    NA    NA    NA    NA    34
#> 4   dog  1980    NA   424    NA    NA    NA
#> 5  lion  1982    NA    NA    NA    12    NA
#> 6 moose  2310    NA    NA   5.6    NA    NA

如果在示例输出中维护行顺序很重要,那么只需在使用rownames_to_column()之前添加spread

df %>% 
  rownames_to_column() %>%
  spread(code, val) 
#> # A tibble: 6 x 8
#>   rowname  name  time    a2    b2    c6    g8    h9
#> *   <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1       1   cat  2012  2321    NA    NA    NA    NA
#> 2       2   dog  1980    NA   424    NA    NA    NA
#> 3       3   cat  2101    NA    NA  34.0    NA    NA
#> 4       4 moose  2310    NA    NA   5.6    NA    NA
#> 5       5   dog  1972    NA    NA    NA    NA    34
#> 6       6  lion  1982    NA    NA    NA    12    NA