R / tidyr / dplyr - 按键将重复的行转换为具有新变量名

时间:2017-10-06 14:52:09

标签: r database dplyr tidyr

编辑:这是与this one类似的问题,但我明确地采用了tidyr / dplyr方法。

我很好奇是否有一种干净的“tidyr / dplyr”方式进行这种转置?

我对目前处于“长”格式的相同现象(关键)有不同的(通过ID)观察(v2,v2,v3),并且为了呈现,我想要一种具有一种现象的宽格式(关键) )每行,但每组观察(ID,v1,v2,v3)在重复的列集中具有适当增加的变量名称

在这种情况下,我知道只有2个ID,所以我把它分成两个表并加入它们。

我想要一个关于转变的一般方式的任何指示:

key ID      v1      v2      v3
32  blue    8.550   0.782   78.281
32  green   9.200   1.680   95.354
22  orange  6.100   -0.143  44.320
22  pink    6.500   0.672   74.920
100 green   4.500   -0.460  32.280
100 blue    8.000   0.506   69.372

分为:

key IDa     v1       v2     v3      IDb     v1b     v2b     v3b
32  blue    8.550    0.782  78.281  green   9.200   1.680   95.354
22  orange  6.100   -0.143  44.320  pink    6.500   0.672   74.920
100 green   4.500   -0.460  32.280  blue    8.000   0.506   69.372

谢谢!

3 个答案:

答案 0 :(得分:2)

您可以为每个创建 id 列,然后使用能够旋转多列的data.table::dcast

df %>% 
    group_by(key) %>% 
    mutate(n = row_number()) %>% 
    {data.table::dcast(data = setDT(.), key ~ n, value.var = c('ID', 'v1', 'v2', 'v3'))}

#   key   ID_1  ID_2 v1_1 v1_2   v2_1  v2_2   v3_1   v3_2
#1:  22 orange  pink 6.10  6.5 -0.143 0.672 44.320 74.920
#2:  32   blue green 8.55  9.2  0.782 1.680 78.281 95.354
#3: 100  green  blue 4.50  8.0 -0.460 0.506 32.280 69.372

答案 1 :(得分:2)

此解决方案仅依赖于tidyrdplyr。这里的关键是使用tidyr::unite创建spread的密钥变量。

library(dplyr)
library(tidyr)

df %>% 
  group_by(key) %>% 
  mutate(suffix = letters[1:n()]) %>%
  gather(var, val, -c(key, suffix)) %>%
  unite(var_group, var, suffix, sep = "") %>%
  spread(var_group, val) %>%
  select(key, ends_with("a"), ends_with("b"))
#> # A tibble: 3 x 9
#> # Groups:   key [3]
#>     key    IDa   v1a    v2a    v3a   IDb   v1b   v2b    v3b
#> * <int>  <chr> <chr>  <chr>  <chr> <chr> <chr> <chr>  <chr>
#> 1    22 orange   6.1 -0.143  44.32  pink   6.5 0.672  74.92
#> 2    32   blue  8.55  0.782 78.281 green   9.2  1.68 95.354
#> 3   100  green   4.5  -0.46  32.28  blue     8 0.506 69.372

答案 2 :(得分:0)

使用反向重复连接(借用的SQL方法)考虑使用merge的基本R解决方案。但是,您需要为反向重复subset的行号创建一个帮助列,并生成不同的IDa值。 transform下方用于删除帮助列。

txt = "key ID      v1      v2      v3
32  blue    8.550   0.782   78.281
32  green   9.200   1.680   95.354
22  orange  6.100   -0.143  44.320
22  pink    6.500   0.672   74.920
100 green   4.500   -0.460  32.280
100 blue    8.000   0.506   69.372"

df <- read.table(text=txt, header=TRUE, stringsAsFactors = FALSE)
df$row <- row.names(df)

mdf <- transform(subset(merge(df, df, by="key", suffixes=c("a", "b")), rowa < rowb), rowa=NULL, rowb=NULL)

mdf
#    key    IDa  v1a    v2a    v3a   IDb v1b   v2b    v3b
# 2   22 orange 6.10 -0.143 44.320  pink 6.5 0.672 74.920
# 6   32   blue 8.55  0.782 78.281 green 9.2 1.680 95.354
# 10 100  green 4.50 -0.460 32.280  blue 8.0 0.506 69.372