将R列的值扩展为具有另一列的值的列标题

时间:2019-05-21 21:26:34

标签: r dataframe datatable pivot expand

我正在尝试扩展如下所示的R数据表:

a   step_num   duration 

1          1          5 
1          2          4
1          3          1
2          1          7
2          2          2
2          3          9
3          1          1
3          2          1
3          3          3

变成这样的东西:

a | step_num | duration | 1_duration | 2_duration | 3_duration |
----------------------------------------------------------------
1          1          5            5           -            -
1          2          4            -           4            -
1          3          1            -           -            1
2          1          7            7           -            -
2          2          2            -           2            -
2          3          9            -           -            9
3          1          1            1           -            -
3          2          1            -           1            -
3          3          3            -           -            3

我想知道是否有一个“扩展”功能,可以这么说。

谢谢!

4 个答案:

答案 0 :(得分:3)

我们可以在 base r 中进行此操作。

cbind(df,
      reshape(df, idvar = c("a","step_num"), timevar = "step_num", direction = "wide")[,-1])

#>   a step_num duration duration.1 duration.2 duration.3
#> 1 1        1        5          5         NA         NA
#> 2 1        2        4         NA          4         NA
#> 3 1        3        1         NA         NA          1
#> 4 2        1        7          7         NA         NA
#> 5 2        2        2         NA          2         NA
#> 6 2        3        9         NA         NA          9
#> 7 3        1        1          1         NA         NA
#> 8 3        2        1         NA          1         NA
#> 9 3        3        3         NA         NA          3

reprex package(v0.2.1)于2019-05-21创建

答案 1 :(得分:3)

或来自dcast的{​​{1}}的选项

data.table

注意:最好使用library(data.table) dcast(setDT(df), a + step_num ~ paste0("duration_", step_num), value.var = 'duration') # a step_num duration_1 duration_2 duration_3 #1: 1 1 5 NA NA #2: 1 2 NA 4 NA #3: 1 3 NA NA 1 #4: 2 1 7 NA NA #5: 2 2 NA 2 NA #6: 2 3 NA NA 9 #7: 3 1 1 NA NA #8: 3 2 NA 1 NA #9: 3 3 NA NA 3 而不是NA,因为-可以通过NA轻松移除,并且不会将列的类更改为{ {1}}

数据

is.na/complete.cases/na.omit

答案 2 :(得分:2)

这是使用dplyrtidyr的方法。

我们获取原始数据,并使用dplyr::bind_cols添加一些列。这些多余的列是通过获取原始数据并添加一个新列col来创建的,该列基于step_num包含我们想要的列标题。然后,根据使用的tidyr::spread,使用col将持续时间放入不同的列中。 fill = "-"用破折号填充所有空白列。最后,我们删除了astep_num列,因为它们已经存在于原始数据中,并且我们不想拥有它们的副本。

(请注意,我们需要step_numspread步骤中仍然存在,因为我们想使每一行与原始行对齐。没有step_num,数据将散布开转换为更宽,更短的格式,从而导致行未对齐。

library(dplyr); library(tidyr)
df %>%  
  bind_cols(df %>%  
              mutate(col = paste0(step_num, "_duration")) %>%
              spread(col, duration, fill = "-") %>%
              select(-a, -step_num))


  a step_num duration 1_duration 2_duration 3_duration
1 1        1        5          5          -          -
2 1        2        4          -          4          -
3 1        3        1          -          -          1
4 2        1        7          7          -          -
5 2        2        2          -          2          -
6 2        3        9          -          -          9
7 3        1        1          1          -          -
8 3        2        1          -          1          -
9 3        3        3          -          -          3

答案 3 :(得分:0)

简单的tidyverse解决方案:

library(tidyverse)

df %>%
  mutate(step = step_num) %>%
  spread(step, duration, fill = '-') %>%
  rename_all( ~ gsub('(\\d+)', 'duration_\\1', .))

#   a step_num duration_1 duration_2 duration_3
# 1 1        1          5          -          -
# 2 1        2          -          4          -
# 3 1        3          -          -          1
# 4 2        1          7          -          -
# 5 2        2          -          2          -
# 6 2        3          -          -          9
# 7 3        1          1          -          -
# 8 3        2          -          1          -
# 9 3        3          -          -          3