我有以下表格的数据:
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中实现这一目标?
答案 0 :(得分:3)
# 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
中的tidyr
和starts_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))