数据框中的前N列及其相应的列名和行名

时间:2018-11-09 13:37:16

标签: r data.table

我有一个数据框,它通过数字来描述用户之间的相似性。代表性数据集如下所示:

    C1  C2  C3  C4  C5  C6  C7  C8  C9 C10
R1  72  71  9   47  77  58  74  52  19  82
R2  43  25  75  100 66  97  71  76  26  57
R3  1   32  87  81  88  66  84  29  15  49
R4  66  68  22  63  40  53  32  69  57  58
R5  42  34  30  77  36  41  61  68  61  35
R6  59  23  38  3   20  86  72  81  58  1
R7  40  86  45  21  44  63  79  77  35  47
R8  15  75  15  19  34  72  96  28  24  38
R9  13  69  2   30  81  72  38  95  92  10
R10 69  26  23  100 55  10  29  16  20  38

我希望每行的 top N 列(例如7个)以及列名和相应的行名。因此它可以是另一个dataframe,如下所述。它可以在一个步骤或多个步骤中形成中间数据帧,以达到此解决方案。

col1 col2 col3
R1  C10 82
R1  C5  77
R1  C7  74
R1  C1  72
R1  C2  71
R1  C6  58
R1  C8  52
R2  C4  100
R2  C6  97
R2  C8  76
R2  C3  75
R2  C7  71
R2  C5  66
R2  C10 57

3 个答案:

答案 0 :(得分:0)

这将是使用dplyr软件包的解决方案。您可以使用melt函数将第一个变量的每个条目的列都变为行。然后,您只需按第一个变量分组,然后为每个分组排列值。最后,您可以分割任意数量的点。在我的示例中,我获得了前7名:

library(dplyr)
df %>% 
  melt(id.vars = first(names(.)),
       measure.vars = names(.)[names(.) != first(names(.))]) %>%
  group_by(!!as.name(first(names(.)))) %>%
  top_n(7)

我建立了它,以便您数据框的名称可以变化。如果您将所有数据框以相同的方式命名,只需将first(names(.))交换为C1(或您喜欢的任何名称),即可对其进行调整。

答案 1 :(得分:0)

这不使用任何软件包。如果要获取data.table结果,请将data.frame替换为data.table

N <- 3
data.frame(row = rownames(DF), 
  value = t(apply(DF, 1, function(x) rev(tail(sort(x), N)))), 
  col = t(apply(DF, 1, function(x) rev(names(DF)[tail(order(x), N)]))))

给予:

    row value.1 value.2 value.3 col.1 col.2 col.3
R1   R1      82      77      74   C10    C5    C7
R2   R2     100      97      76    C4    C6    C8
R3   R3      88      87      84    C5    C3    C7
R4   R4      69      68      66    C8    C2    C1
R5   R5      77      68      61    C4    C8    C9
R6   R6      86      81      72    C6    C8    C7
R7   R7      86      79      77    C2    C7    C8
R8   R8      96      75      72    C7    C2    C6
R9   R9      95      92      81    C8    C9    C5
R10 R10     100      69      55    C4    C1    C5

注意

可重复形式的输入DF为:

Lines <- "C1 C2 C3  C4  C5  C6  C7  C8  C9 C10
R1 72 71 9 47 77 58 74 52 19 82
R2 43 25 75 100 66 97 71 76 26 57
R3 1 32 87 81 88 66 84 29 15 49
R4 66 68 22 63 40 53 32 69 57 58
R5 42 34 30 77 36 41 61 68 61 35
R6 59 23 38 3 20 86 72 81 58 1
R7 40 86 45 21 44 63 79 77 35 47
R8 15 75 15 19 34 72 96 28 24 38
R9 13 69 2 30 81 72 38 95 92 10
R10 69 26 23 100 55 10 29 16 20 38"
DF <- read.table(text = Lines)

答案 2 :(得分:0)

这是基于R的另一种解决方案:

D <- read.table(header=TRUE, text=
"    C1  C2  C3  C4  C5  C6  C7  C8  C9 C10
R1  72  71  9   47  77  58  74  52  19  82
R2  43  25  75  100 66  97  71  76  26  57
R3  1   32  87  81  88  66  84  29  15  49
R4  66  68  22  63  40  53  32  69  57  58
R5  42  34  30  77  36  41  61  68  61  35
R6  59  23  38  3   20  86  72  81  58  1
R7  40  86  45  21  44  63  79  77  35  47
R8  15  75  15  19  34  72  96  28  24  38
R9  13  69  2   30  81  72  38  95  92  10
R10 69  26  23  100 55  10  29  16  20  38")
top7 <- function(x) { y <- x[order(x, decreasing = TRUE)[1:7]] ; data.frame(Col=names(y), value=y) 
}
L <- apply(D[,], 1, top7)
result <- L[[1]]
for (i in 2:length(L)) result <- rbind(result, L[[i]])
data.frame(Row=rep(rownames(D), each=7), result, row.names = NULL)

给予:

> data.frame(Row=rep(rownames(D), each=7), result, row.names = NULL)
   Row Col value
1   R1 C10    82
2   R1  C5    77
3   R1  C7    74
4   R1  C1    72
5   R1  C2    71
6   R1  C6    58
7   R1  C8    52
8   R2  C4   100
9   R2  C6    97
10  R2  C8    76
11  R2  C3    75
12  R2  C7    71
13  R2  C5    66
14  R2 C10    57
15  R3  C5    88
16  R3  C3    87
17  R3  C7    84
18  R3  C4    81
19  R3  C6    66
20  R3 C10    49
21  R3  C2    32
22  R4  C8    69
23  R4  C2    68
24  R4  C1    66
25  R4  C4    63
26  R4 C10    58
27  R4  C9    57
28  R4  C6    53
29  R5  C4    77
30  R5  C8    68
31  R5  C7    61
32  R5  C9    61
33  R5  C1    42
34  R5  C6    41
35  R5  C5    36
36  R6  C6    86
37  R6  C8    81
38  R6  C7    72
39  R6  C1    59
40  R6  C9    58
41  R6  C3    38
42  R6  C2    23
43  R7  C2    86
44  R7  C7    79
45  R7  C8    77
46  R7  C6    63
47  R7 C10    47
48  R7  C3    45
49  R7  C5    44
50  R8  C7    96
51  R8  C2    75
52  R8  C6    72
53  R8 C10    38
54  R8  C5    34
55  R8  C8    28
56  R8  C9    24
57  R9  C8    95
58  R9  C9    92
59  R9  C5    81
60  R9  C6    72
61  R9  C2    69
62  R9  C7    38
63  R9  C4    30
64 R10  C4   100
65 R10  C1    69
66 R10  C5    55
67 R10 C10    38
68 R10  C7    29
69 R10  C2    26
70 R10  C3    23

或(按等级)

data.frame(Row=rep(rownames(D), each=7), Rank=1:7, result, row.names = NULL)