通过列名开头从tidyr收集从长到长的格式

时间:2016-05-20 16:24:00

标签: r dplyr tidyr

obs pre.data1   post.data1  pre.data2   post.data2  pre.data3   post.data3
1   0.40    0.12    0.61    0.15    0.58    0.06
2   0.21    0.05    0.18    0.49    0.35    0.24
3   0.48    0.85    0.00    0.62    0.96    0.37
4   0.66    0.29    0.88    0.56    0.13    0.72
5   0.43    0.23    0.80    0.78    0.05    0.90
6   0.86    0.04    0.25    0.34    0.99    0.79
7   0.57    0.86    0.20    0.34    0.11    0.34
8   0.13    0.39    0.24    0.51    0.79    0.63
9   0.87    0.57    0.00    0.55    0.86    0.72

我上面附上了我的数据集示例。

我正在尝试使用基于每个变量前后的前缀的tidyr从宽格式转换为长格式。理想情况下,我希望我的数据采用以下格式

obs key    data1    data2   data3
1   pre     0.50    0.26    0.12
1   post    0.18    0.50    0.42
2   pre     0.06    0.07    0.47
2   post    0.98    0.87    0.89
3   pre     0.34    0.55    0.72
3   post    0.26    0.99    0.71
4   pre     0.64    0.80    0.54
4   post    0.01    0.36    0.38

我对R很新,但我知道它使用了收集功能,但我只熟悉收集2列,如许多教程所示。有没有一种简单的方法来做上述事情?谢谢

2 个答案:

答案 0 :(得分:3)

我们可以使用data.table作为melt中的data.table轻松完成此操作(从'宽'转换为' long'格式)可以为patterns列添加多个measure

library(data.table)
dM <- melt(setDT(df1), measure = patterns("data1$", "data2", "data3"), 
    value.name = c('data1', 'data2', 'data3'), variable.name = 'key')
dM[, key:= unique(sub("\\..*", "", names(df1)[-1]))[key]]
dM[order(obs)]
#    obs  key data1 data2 data3
# 1:   1  pre  0.40  0.61  0.58
# 2:   1 post  0.12  0.15  0.06
# 3:   2  pre  0.21  0.18  0.35
# 4:   2 post  0.05  0.49  0.24
# 5:   3  pre  0.48  0.00  0.96
# 6:   3 post  0.85  0.62  0.37
# 7:   4  pre  0.66  0.88  0.13
# 8:   4 post  0.29  0.56  0.72
# 9:   5  pre  0.43  0.80  0.05
#10:   5 post  0.23  0.78  0.90
#11:   6  pre  0.86  0.25  0.99
#12:   6 post  0.04  0.34  0.79
#13:   7  pre  0.57  0.20  0.11
#14:   7 post  0.86  0.34  0.34
#15:   8  pre  0.13  0.24  0.79
#16:   8 post  0.39  0.51  0.63
#17:   9  pre  0.87  0.00  0.86
#18:   9 post  0.57  0.55  0.72

或者使用tidyr,我们会将其转换为“长期&#39;格式为gather,然后是separate&#39; Var&#39;列到&#39;键&#39;和&#34; Var2&#39;并且spread它到广泛的&#39;格式。

library(dplyr)
library(tidyr)
gather(df1, Var, Val, -obs) %>% 
      separate(Var, into = c("key", "Var2")) %>% 
       mutate(key = factor(key, levels = c("pre", "post"))) %>%
      spread(Var2, Val)
#   obs  key data1 data2 data3
#1    1  pre  0.40  0.61  0.58
#2    1 post  0.12  0.15  0.06
#3    2  pre  0.21  0.18  0.35
#4    2 post  0.05  0.49  0.24
#5    3  pre  0.48  0.00  0.96
#6    3 post  0.85  0.62  0.37
#7    4  pre  0.66  0.88  0.13
#8    4 post  0.29  0.56  0.72
#9    5  pre  0.43  0.80  0.05
#10   5 post  0.23  0.78  0.90
#11   6  pre  0.86  0.25  0.99
#12   6 post  0.04  0.34  0.79
#13   7  pre  0.57  0.20  0.11
#14   7 post  0.86  0.34  0.34
#15   8  pre  0.13  0.24  0.79
#16   8 post  0.39  0.51  0.63
#17   9  pre  0.87  0.00  0.86
#18   9 post  0.57  0.55  0.72

也可以使用reshape中的base R来完成此操作(但是,可能需要进行一些后处理才能使其整洁)

reshape(df1, idvar="obs", varying = list(2:3, 4:5, 6:7), direction="long")

答案 1 :(得分:3)

let url = NSURL(string: "https://www.google.co.uk") let request = NSMutableURLRequest(URL: url!) let session = NSURLSession.sharedSession() let task = session.dataTaskWithRequest(request) { (data, response, error) in guard (error == nil) else { print("ERROR: error occured in request: \(request) \(error)") return } if let statusCode = (response as? NSHTTPURLResponse)?.statusCode { switch(statusCode) { case 200...299: print("should be good") case 400: print("bad request") default: print("Unknown status code received: \(statusCode)") } } }

tidyr