展平 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
的内置(高效)相当于 reshape2
的 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
如果您希望名称与您在 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
更新: 我一直在这里搜索相关问题,但似乎找不到我要找的东西。我需要展平一些嵌套数据。我的数据框目前看起来像这样:
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
的内置(高效)相当于 reshape2
的 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
如果您希望名称与您在 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