展平 R 中的嵌套数据

flatten nested data in R

更新: 我一直在这里搜索相关问题,但似乎找不到我要找的东西。我需要展平一些嵌套数据。我的数据框目前看起来像这样:

Col_A | Col B
red   | 1
red   | 2
red   | 4
red   | 5
blue  | 2
blue  | 2
blue  | 3
green | 1
green | 2
green | 3
green | 3
green | 7
green | 9
black | 4
orange| 1
orange| 2

不过,我希望它看起来像这样:

A     | B | C | D | E | F | G |
red   | 1 | 2 | 4 | 5 | NA| NA|
blue  | 2 | 2 | 3 | NA| NA| NA|
green | 1 | 2 | 3 | 3 | 7 | 9 |
black | 4 | NA| NA| NA| NA| NA|
orange| 1 | 2 | NA| NA| NA| NA|

我尝试使用 dplyr::group_by() 但显然我没有正确理解它,因为它对我的数据框没有任何作用。有任何想法吗?我假设有一个非常 straightforward/simple 的函数可以为我做这件事。如果没有,我想我可以试着把它循环出来:(

在此先感谢您的帮助!

您正在 tidyr 包中查找 spread。如果您的数据如下所示:

d <- data.frame(Col_A = rep(c("red", "blue", "green", "black", "orange"), c(4, 3, 6, 1, 2)),
                Col_B = c(1:4, 1:3, 1:6, 1, 1:2))

那么你可以这样做:

spread(d, Col_B, Col_B)
#>    Col_A 1  2  3  4  5  6
#> 1  black 1 NA NA NA NA NA
#> 2   blue 1  2  3 NA NA NA
#> 3  green 1  2  3  4  5  6
#> 4 orange 1  2 NA NA NA NA
#> 5    red 1  2  3  4 NA NA

请注意,您的分布情况有点奇怪,因为您使用相同的值分布在各列中并填充值。看起来您希望根据字母命名列。一种方法是:

d %>%
    mutate(letter = LETTERS[Col_B + 1]) %>%
    spread(letter, Col_B)
#>    Col_A B  C  D  E  F  G
#> 1  black 1 NA NA NA NA NA
#> 2   blue 1  2  3 NA NA NA
#> 3  green 1  2  3  4  5  6
#> 4 orange 1  2 NA NA NA NA
#> 5    red 1  2  3  4 NA NA

但是,如何重命名列的细节取决于您的特定数据。

使用 reshape2 包的解决方案。 添加具有未来列名称的列并将 data.frame 转换为新的 data.frame.

d <- data.frame(Col_A = rep(c("red", "blue", "green", "black", "orange"), c(4, 3, 6, 1, 2)), 
                Col_B = c(1:4, 1:3, 1:6, 1, 1:2))
d$L <- LETTERS[d$Col_B + 1]
reshape2::dcast(d, Col_A ~ L, value.var = "Col_B")

#output
   Col_A B  C  D  E  F  G
1  black 1 NA NA NA NA NA
2   blue 1  2  3 NA NA NA
3  green 1  2  3  4  5  6
4 orange 1  2 NA NA NA NA
5    red 1  2  3  4 NA NA

使用 data.table 的内置(高效)相当于 reshape2dcast:

library(data.table) #1.9.5+, use dcast.data.table in earlier versions
setDT(x)
> dcast(x[, .(Col_B,1:.N), by=Col_A], Col_A~V2, value.var="Col_B")
    Col_A 1  2  3  4  5  6
1: black  4 NA NA NA NA NA
2: blue   2  2  3 NA NA NA
3: green  1  2  3  3  7  9
4: orange 1  2 NA NA NA NA
5: red    1  2  4  5 NA NA

如果 Col_A 已经存储在您的 data.frame 中作为具有适当级别排序的因素,dcast 将保留此顺序,否则我们可能会指定:

x$Col_A<-factor(x$Col_A, levels=unique(x$Col_A))
setDT(x)
> dcast(x[, .(Col_B,1:.N), by=Col_A], Col_A~V2, value.var="Col_B")
    Col_A 1  2  3  4  5  6
1: red    1  2  4  5 NA NA
2: blue   2  2  3 NA NA NA
3: green  1  2  3  3  7  9
4: black  4 NA NA NA NA NA
5: orange 1  2 NA NA NA NA

如果您希望名称与您在 post 中所写的一样,请使用 setnames:

setnames(dcast(x[,.(Col_B,1:.N),by=Col_A],
               Col_A~V2,value.var="Col_B"),
         LETTERS[1:7])[]
        A B  C  D  E  F  G
1: red    1  2  4  5 NA NA
2: blue   2  2  3 NA NA NA
3: green  1  2  3  3  7  9
4: black  4 NA NA NA NA NA
5: orange 1  2 NA NA NA NA