将多个列合并为一个具有R

时间:2015-05-21 14:37:27

标签: r dplyr

我有以下表格的数据:

Id1      Id21    c1      Id22    c2      Id23     c3      Id24       c4    
1         20      5        11     9        9      20       32        10
1         40      4        14     9        13      5       36         9
1         43      3        15     3        23      1       39         8     
2         47      5        17     8        11      9       10         5
2         5       4        12     8        14      8       28         4      
2         6       0        10     2        24      4       23         2
3         .       .         .     .         .      .       .          .
3         .       .         .     .         .      .       .          .
3          
4
.
.
100
100
100

每个Id有三个条目的Id1具有相应的Id2i和ci,i - > [1,4] 这样,id2i总是按递增顺序排列,并且每个id1的ci总是递减。 我需要输出:

Id1    Id2     c
1       9      20
1       32     10  
1       11     9
1       14     9
1       36     9
2       11     9
2       17     8
2       12     8
2       14     8
2       47     5
.
.
.
100
100
100
100
100     .      .

因此,对于id1中每个id的五个条目,从所有ci中选择前5个c,使得c(输出)是所有ci的最大组。 如何在R中实现这一目标?

3 个答案:

答案 0 :(得分:3)

使用dev version of data.table

# using first six rows from your post
require(data.table) # v1.9.5+
ans <- melt(setDT(df), measure = patterns(c("^Id2", "^c[0-9]$"))
         value.name = c("Id2", "c"))
ans[order(-c), head(.SD, 5L), by=Id1, .SDcols = -(variable)]
#     Id1 Id2  c
#  1:   1   9 20
#  2:   1  32 10
#  3:   1  11  9
#  4:   1  14  9
#  5:   1  36  9
#  6:   2  11  9
#  7:   2  17  8
#  8:   2  12  8
#  9:   2  14  8
# 10:   2  47  5

基本上,melt可以接受列名列表,以将列表中每个元素的列分组到单独的列中。查看lapply(...)的结果,了解哪些列组合在一起。

然后,按Id1列按降序排序后,我们按c分组,然后从属于每个组的数据子集中选择前5行。

答案 1 :(得分:2)

您可以使用gather中的tidyrstarts_with中的dplyr来执行此操作。

require(tidyr)
require(dplyr)

df %>% 
  gather(key = "Id2_key", value = "Id2", starts_with("Id2")) %>%
  gather(key = "c_key", value = "c", starts_with("c"))
##    Id1 Id2_key Id2 c_key  c
## 1    1    Id21  20    c1  5
## 2    1    Id21  40    c1  4
## 3    1    Id21  43    c1  3
## 4    2    Id21  47    c1  5
## 5    2    Id21   5    c1  4
## 6    2    Id21   6    c1  0
## ...                     ...

答案 2 :(得分:1)

#Try this: (df is your original dataframe)
     library(reshape2)
        df1<melt(df,measure.vars=paste0("c",1:4),variable.name="c",value.name="c_value")
        df2<-melt(df1,measure.vars=paste0("Id2",1:4),variable.name="Id2",value.name="Id2_value")
head(df2)

  Id1  c c_value  Id2 Id2_value
1   1 c1       5 Id21        20
2   1 c1       4 Id21        40
3   1 c1       3 Id21        43
4   2 c1       5 Id21        47
5   2 c1       4 Id21         5
6   2 c1       0 Id21         6

#data
df<-
structure(list(Id1 = c(1L, 1L, 1L, 2L, 2L, 2L), Id21 = c(20L, 
40L, 43L, 47L, 5L, 6L), c1 = c(5L, 4L, 3L, 5L, 4L, 0L), Id22 = c(11L, 
14L, 15L, 17L, 12L, 10L), c2 = c(9L, 9L, 3L, 8L, 8L, 2L), Id23 = c(9L, 
13L, 23L, 11L, 14L, 24L), c3 = c(20L, 5L, 1L, 9L, 8L, 4L), Id24 = c(32L, 
36L, 39L, 10L, 28L, 23L), c4 = c(10L, 9L, 8L, 5L, 4L, 2L)), .Names = c("Id1", 
"Id21", "c1", "Id22", "c2", "Id23", "c3", "Id24", "c4"), class = "data.frame", row.names = c(NA, 
-6L))