2017-04-08 83 views
2

我想将两个独立的列组收集到两个键值对中。下面是一些示例性数据:使用gather()将两个(或更多)列组收集到两个(或更多)键值对中

library(dplyr) 
library(tidyr) 
ID = c(1:5) 
measure1 = c(1:5) 
measure2 = c(6:10) 
letter1 = c("a", "b", "c", "d", "e") 
letter2 = c("f", "g", "h", "i", "j") 

df = data.frame(ID, measure1, measure2, letter1, letter2) 
df = tbl_df(df) 
df$letter1 <- as.character(df$letter1) 
df$letter2 <- as.character(df$letter2) 

我希望两个量度列(措施1和measure2)的值是在一列中具有键柱旁边(键 - 值对)。我也希望letter1和letter2一样。我想,我可以使用select()创建两个不同的数据集,用两个数据集seperately收集,然后加入(这工作):

df_measure = df %>% 
    select(ID, measure1, measure2) %>% 
    gather(measure_time, measure, -ID) %>% 
    mutate(id.extra = c(1:10)) 
df_letter = df %>% 
    select(ID, letter1, letter2) %>% 
    gather(letter_time, letter, -ID) %>% 
    mutate(id.extra = c(1:10)) 
df_long = df_measure %>% 
    left_join(df_letter, by = "id.extra") 

所以这完美的作品(在这种情况下),但我想这可以做得更优雅(没有像分裂或创建'id.extra'之类的东西),所以请说明一下吧!

回答

3

您可以使用类似下面的内容。我不确定从目前的方法,如果这正是你想要的输出或不,因为它似乎包含大量的冗余信息。

df %>% 
    gather(val, var, -ID) %>% 
    extract(val, c("value", "time"), regex = "([a-z]+)([0-9]+)") %>% 
    spread(value, var) 
# # A tibble: 10 × 4 
#  ID time letter measure 
# * <int> <chr> <chr> <chr> 
# 1  1  1  a  1 
# 2  1  2  f  6 
# 3  2  1  b  2 
# 4  2  2  g  7 
# 5  3  1  c  3 
# 6  3  2  h  8 
# 7  4  1  d  4 
# 8  4  2  i  9 
# 9  5  1  e  5 
# 10  5  2  j  10 

这是更容易与melt + patterns完成从 “data.table”:

library(data.table) 
melt(as.data.table(df), measure.vars = patterns("measure", "letter")) 

或者你也可以是老派的,只是使用reshape从基地R.但是,请注意,基础R的reshape不喜欢“蹒跚”,所以你必须将它与as.data.frame转换)。

reshape(as.data.frame(df), direction = "long", idvar = "ID", 
     varying = 2:ncol(df), sep = "") 
+0

的聚拢()函数不能做到这一点? –

+1

@BenjaminTelkamp,不能做什么?我在第一种方法中使用了“收集”功能。但是,你必须收集*所有的列,然后将它们分开。 – A5C1D2H2I1M1N2O1R2T1

1

我们可以使用从data.tablemelt可以采取多种measurepatterns

library(data.table) 
melt(setDT(df), measure = patterns("^measure", "^letter"), 
      value.name = c("measure", "letter")) 
#  ID variable measure letter 
# 1: 1  1  1  a 
# 2: 2  1  2  b 
# 3: 3  1  3  c 
# 4: 4  1  4  d 
# 5: 5  1  5  e 
# 6: 1  2  6  f 
# 7: 2  2  7  g 
# 8: 3  2  8  h 
# 9: 4  2  9  i 
#10: 5  2  10  j 
+0

这看起来不错,但是如果我想在代码中显式使用columnn或变量名称,我该怎么办?而且我想结束两个键值对? –

+1

@BenjaminTelkamp,只是复制“变量”列....你为什么要重复数据? – A5C1D2H2I1M1N2O1R2T1

+0

在这种情况下,我有两个意见的措施和字母,但如果我有一个组的三个意见? –

相关问题