我在R
中具有以下数据框:
Date | ID | Shape | Size | Color
---- | -- | ----- | ---- | ----
1/1/1| 01 | RND | L | RED
1/1/1| 02 | RND | M | BRN
1/1/1| 03 | SQR | S | BLK
1/2/1| 01 | TRI | S | GRN
1/2/1| 02 | SQR | L | BLK
1/2/1| 03 | RND | L | BLU
1/3/1| 01 | OVL | M | YEL
1/3/1| 02 | STR | L | ORA
1/3/1| 03 | CUB | S | PUR
... | .. | ... | ... | ...
我想将此数据帧转换为以下单独的数据帧:
df_shape:
Date | Shape.id1 | Shape.id2 | Shape.id3
---- | --------- | --------- | ---------
1/1/1| RND | RND | SQR
1/2/1| TRI | SQR | RND
1/3/1| OVL | STR | CUB
... | ... | ... | ...
df_size:
Date | Size.id1 | Size.id2 | Size.id3
---- | --------- | --------- | ---------
1/1/1| L | M | S
1/2/1| S | L | L
1/3/1| M | L | S
... | ... | ... | ...
df_color:
Date | Color.id1 | Color.id2| Color.id3
---- | --------- | ---------| ---------
1/1/1| RED | BRN | BLK
1/2/1| GRN | BLK | BLU
1/3/1| YEL | ORA | PUR
... | ... | ... | ...
我知道tidyr
和spread()
可能是完美的情况,但是我不确定如何真正完成这项工作。
key, value
组合是什么?谢谢!
答案 0 :(得分:1)
好吧,你可以做:
df_shape <- df %>% distinct(Date, ID, Shape) %>%
mutate(ID = paste0("Shape.id", ID)) %>%
spread(ID, Shape)
df_size <- df %>% distinct(Date, ID, Size) %>%
mutate(ID = paste0("Size.id", ID)) %>%
spread(ID, Size)
df_color <- df %>% distinct(Date, ID, Color) %>%
mutate(ID = paste0("Color.id", ID)) %>%
spread(ID, Color)
答案 1 :(得分:1)
我将使用R附带的iris
数据集来创建示例,并使用“ tidyverse”中的程序包。首先,我将创建一个date
变量,以使iris
看起来更像您的数据集。
library(purrr)
library(dplyr)
library(tidyr)
d <- mutate(iris, date = rep(1:50, 3))
创建一个variables
对象,其中元素是您想要spread
的变量,而元素的名称是数据框的名称:
variables <- setNames(names(iris)[1:4], paste0("df_", names(iris)[1:4]))
# df_Sepal.Length df_Sepal.Width df_Petal.Length df_Petal.Width
# "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
现在,我们使用map
来遍历variables
。
out <- map(variables, function(f) {
select(d, date, Species, f) %>%
spread(key = Species, value = f) %>%
rename_at(2:4, ~paste0(f, "_", .))
})
out
如下所示:
str(out)
# List of 4
# $ df_Sepal.Length:'data.frame': 50 obs. of 4 variables:
# ..$ date : int [1:50] 1 2 3 4 5 6 7 8 9 10 ...
# ..$ Sepal.Length_setosa : num [1:50] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
# ..$ Sepal.Length_versicolor: num [1:50] 7 6.4 6.9 5.5 6.5 5.7 6.3 4.9 6.6 5.2 ...
# ..$ Sepal.Length_virginica : num [1:50] 6.3 5.8 7.1 6.3 6.5 7.6 4.9 7.3 6.7 7.2 ...
# $ df_Sepal.Width :'data.frame': 50 obs. of 4 variables:
# ..$ date : int [1:50] 1 2 3 4 5 6 7 8 9 10 ...
# ..$ Sepal.Width_setosa : num [1:50] 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
# ..$ Sepal.Width_versicolor: num [1:50] 3.2 3.2 3.1 2.3 2.8 2.8 3.3 2.4 2.9 2.7 ...
# ..$ Sepal.Width_virginica : num [1:50] 3.3 2.7 3 2.9 3 3 2.5 2.9 2.5 3.6 ...
# $ df_Petal.Length:'data.frame': 50 obs. of 4 variables:
# ..$ date : int [1:50] 1 2 3 4 5 6 7 8 9 10 ...
# ..$ Petal.Length_setosa : num [1:50] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
# ..$ Petal.Length_versicolor: num [1:50] 4.7 4.5 4.9 4 4.6 4.5 4.7 3.3 4.6 3.9 ...
# ..$ Petal.Length_virginica : num [1:50] 6 5.1 5.9 5.6 5.8 6.6 4.5 6.3 5.8 6.1 ...
# $ df_Petal.Width :'data.frame': 50 obs. of 4 variables:
# ..$ date : int [1:50] 1 2 3 4 5 6 7 8 9 10 ...
# ..$ Petal.Width_setosa : num [1:50] 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
# ..$ Petal.Width_versicolor: num [1:50] 1.4 1.5 1.5 1.3 1.5 1.3 1.6 1 1.3 1.4 ...
# ..$ Petal.Width_virginica : num [1:50] 2.5 1.9 2.1 1.8 2.2 2.1 1.7 1.8 1.8 2.5 ...
您可以将out
保留为数据帧列表,也可以使用
list2env(out, envir = globalenv())
将列表组件分配到全局环境中。