在R中展平嵌套数据

时间:2015-08-28 21:56:13

标签: r nested

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

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(),但显然我不能正确理解它,因为它对我的数据框没有任何作用。有任何想法吗?我认为这是一个非常简单/简单的功能,可以为我做到这一点。如果没有,我想我可以尝试将其循环:(

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:5)

您正在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

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

答案 1 :(得分:1)

使用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

答案 2 :(得分:1)

使用data.table内置(有效)等效于reshape2&#39; s dcast

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

如果您希望姓名与您在帖子中所写的一样,请使用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