R 按id从宽到长收集列

R 按id从宽到长收集列,r,reshape,R,Reshape,我有这样一个数据框: set.seed(100) drugs <- data.frame(id = 1:5, drug_1 = letters[1:5], drug_dos_1 = sample(100,5), drug_2 = letters[3:7], drug_dos_2 = sample(100,5) ) id drug_1 drug_dos_1 drug_2 drug_dos_2 1 a

我有这样一个数据框:

set.seed(100)

drugs <- data.frame(id = 1:5, 
                drug_1 = letters[1:5], drug_dos_1 = sample(100,5),
                drug_2 = letters[3:7], drug_dos_2 = sample(100,5)
)

id drug_1 drug_dos_1 drug_2 drug_dos_2
1      a         31      c         49
2      b         26      d         81
3      c         55      e         37
4      d          6      f         54
5      e         45      g         17

我想这可以通过使用一个重塑函数来实现,该函数可以将数据从宽格式转换为长格式,但我没有管理。

一个选项是
数据中熔化
。table
可以在
measure
参数中采用多个
模式

library(data.table)
melt(setDT(drugs), measure = patterns('^drug_\\d+$', 'dos'),
     value.name = c('drug', 'dosage'))[, variable := NULL][order(id)]
#   id drug dosage
#1:  1    a     31
#2:  1    c     49
#3:  2    b     26
#4:  2    d     81
#5:  3    c     55
#6:  3    e     37
#7:  4    d      6
#8:  4    f     54
#9:  5    e     45
#10  5    g     17
在这里,“药物”在所有列中都很常见,因此我们需要创建一个独特的模式。一种方法是指定起始位置(
^
),后跟“drug”子字符串,然后在字符串的末尾(
$
)加下划线(
))和一个或多个数字(
\\d+
)。对于“dos”,只需使用该子字符串匹配具有“dos”的列名

库(dplyr)
library(dplyr)
drugs %>% gather(key,val,-id) %>% mutate(key=gsub('_\\d','',key)) %>% #replace _1 and _2 at the end wiht nothing
          mutate(key=gsub('drug_','',key)) %>% group_by(key) %>%  #replace drug_ at the start of dos with nothin and gruop by key
          mutate(row=row_number()) %>% spread(key,val) %>%
          select(id,drug,dos,-row)


 # A tibble: 10 x 3
  id drug  dos  
  <int> <chr> <chr>
  1     1 a     31   
  2     1 c     49   
  3     2 b     26   
  4     2 d     81   
  5     3 c     55   
  6     3 e     37   
  7     4 d     6    
  8     4 f     54   
  9     5 e     45   
 10     5 g     17   
  Warning message:
  attributes are not identical across measure variables;
  they will be dropped
#This warning generated as we merged drug(chr) and dose(num) into one column (val) 
药物%>%聚集(key,val,-id)%%>%突变(key=gsub(“'''\\d','',key))%%>%,在没有任何变化的情况下替换1和2 变异(key=gsub('druge_u','',key))%%>%groupby(key)%%>%#在dos开始时用nothin替换druge_u,并按key替换gruop 变异(row=row_number())%%>%spread(key,val)%%>% 选择(id、药物、dos,-行) #一个tibble:10x3 身份证 1 a 31 2 1 c 49 3 2 b 26 42D81 5 3 c 55 6 3 e 37 7 4 d 6 8 4 f 54 9 5 e 45 10 5 g 17 警告信息: 不同度量变量的属性不相同; 它们将被丢弃 #当我们将药物(chr)和剂量(num)合并到一列(val)时生成此警告
library(dplyr)
drugs %>% gather(key,val,-id) %>% mutate(key=gsub('_\\d','',key)) %>% #replace _1 and _2 at the end wiht nothing
          mutate(key=gsub('drug_','',key)) %>% group_by(key) %>%  #replace drug_ at the start of dos with nothin and gruop by key
          mutate(row=row_number()) %>% spread(key,val) %>%
          select(id,drug,dos,-row)


 # A tibble: 10 x 3
  id drug  dos  
  <int> <chr> <chr>
  1     1 a     31   
  2     1 c     49   
  3     2 b     26   
  4     2 d     81   
  5     3 c     55   
  6     3 e     37   
  7     4 d     6    
  8     4 f     54   
  9     5 e     45   
 10     5 g     17   
  Warning message:
  attributes are not identical across measure variables;
  they will be dropped
#This warning generated as we merged drug(chr) and dose(num) into one column (val)