用tidyr收集两组专栏

时间:2016-10-20 04:40:37

标签: r tidyr

我有这个示例数据集,包含3个处理,3个类(o,l,h)的两个响应变量(D,var):

#        fungic   D_o Var_o   D_l Var_l   D_h Var_h
#    1    AZ_BF 343.6 25756 223.8 20127 442.5 22843
#    2 AZ_CIPRO 186.6 25756  58.2 20127 311.7 22843
#    3  AZ_SOLA 382.6 25756 205.6 20127 520.5 22843


  d =  structure(list(fungic = c("AZ_BF", "AZ_CIPRO", "AZ_SOLA"), D_o = c(343.6, 186.6, 382.6), Var_o = c(25756L, 25756L, 25756L), D_l = c(223.8, 
58.2, 205.6), Var_l = c(20127L, 20127L, 20127L), D_h = c(442.5, 
311.7, 520.5), Var_h = c(22843L, 22843L, 22843L)), .Names = c("fungic", 
"D_o", "Var_o", "D_l", "Var_l", "D_h", "Var_h"), row.names = c(NA,3L), class = "data.frame")

我想收集具有相同第二部分col列的列,即所有D在一起,并且所有Var在一起,保持类级别, 像这样:

     fungic C     D   Var
1     AZ_BF o 343.6 25756
4     AZ_BF o 223.8 25756
7     AZ_BF o 442.5 25756
10    AZ_BF l 343.6 20127
13    AZ_BF l 223.8 20127
16    AZ_BF l 442.5 20127
19    AZ_BF h 343.6 22843
22    AZ_BF h 223.8 22843
25    AZ_BF h 442.5 22843
2  AZ_CIPRO o 186.6 25756
5  AZ_CIPRO o  58.2 25756
8  AZ_CIPRO o 311.7 25756
11 AZ_CIPRO l 186.6 20127
14 AZ_CIPRO l  58.2 20127
17 AZ_CIPRO l 311.7 20127
20 AZ_CIPRO h 186.6 22843
23 AZ_CIPRO h  58.2 22843
26 AZ_CIPRO h 311.7 22843
3   AZ_SOLA o 382.6 25756
6   AZ_SOLA o 205.6 25756
9   AZ_SOLA o 520.5 25756
12  AZ_SOLA l 382.6 20127
15  AZ_SOLA l 205.6 20127
18  AZ_SOLA l 520.5 20127
21  AZ_SOLA h 382.6 22843
24  AZ_SOLA h 205.6 22843
27  AZ_SOLA h 520.5 22843

我用这个可怕的代码做到了......

d1 = d %>% gather(var_Class, D, starts_with("D_")) %>% 
  gather(C, Var, starts_with("Var_")) 
d2 = d1[1:27,]  
d3 = d2 %>% mutate(C=sapply(strsplit(C, split='_', fixed=TRUE),function(x) (x[2])))
d3 = d3[order(d3$fungic),]

有人可以帮助改善吗?我真的不想擅长excel ..

你是完全正确的@akrun,但我完全错了......

对不起,我其实需要这个:

fungic  class       D     var
AZ_BF       o   343.6   25756
AZ_CIPRO    o   186.6   25756
AZ_SOLA     o   382.6   25756
AZ_BF       l   223.8   20127
AZ_CIPRO    l   58.2    20127
AZ_SOLA     l   205.6   20127
AZ_BF       h   442.5   22843
AZ_CIPRO    h   311.7   22843
AZ_SOLA     h   520.5   22843

2 个答案:

答案 0 :(得分:2)

我们可以先使用gather创建一个3列的data.frame,一个用于id(“fungic”),一个用于其余列的名称,另一个用于值。然后,我们为列名的前缀和后缀创建两个变量。最后,我们使用spread将数据转换为宽格式。

d %>% 
    gather(vrb, val, -fungic) %>% 
    mutate(D_Var = gsub("(.*)\\_(.*)", "\\1", vrb), 
           class = gsub("(.*)\\_(.*)", "\\2", vrb)) %>% 
    select(-vrb) %>% 
    spread(D_Var, val) %>% 
    arrange(desc(class))

输出:

#     fungic class     D   Var
# 1    AZ_BF     o 343.6 25756
# 2 AZ_CIPRO     o 186.6 25756
# 3  AZ_SOLA     o 382.6 25756
# 4    AZ_BF     l 223.8 20127
# 5 AZ_CIPRO     l  58.2 20127
# 6  AZ_SOLA     l 205.6 20127
# 7    AZ_BF     h 442.5 22843
# 8 AZ_CIPRO     h 311.7 22843
# 9  AZ_SOLA     h 520.5 22843

答案 1 :(得分:1)

将第一个gatherseparate'var_Class'分成两列后,删除不需要的列,应用第二个gather,删除'Var'和{{ 1}}''fungic'

arrange