我的数据集如下所示:
group <- c(1,2,3,4,5,6,7)
item1.sep <- sample(1:10,7)
item2.sep <- sample(1:10,7)
item3.sep<- sample(1:10,7)
item4.sep<- sample(1:10,7)
item5.sep<- sample(1:10,7)
item1.oct<- sample(1:10,7)
item2.oct <- sample(1:10,7)
item3.oct<- sample(1:10,7)
item4.oct<- sample(1:10,7)
item5.oct<- sample(1:10,7)
df <- data.frame(group,item1.sep,item2.sep,item3.sep,item4.sep,item5.sep,
item1.oct,item2.oct,item3.oct,item4.oct,item5.oct)
group item1.sep item2.sep.... item5.oct
1 9 9 4
2 4 4 7
3 7 7 2
4 3 8 5
5 8 3 1
6 6 10 8
7 10 2 6
我想创建2个新列,每个月包含前2项作为字符。也许max和merge的组合对这个有帮助
Top2_Sept Top2_Oct group.... item5.oct
item3.sep,item2.sep item5.Oct,item2.Oct 1 9
item4.sep,item1.sep . 2 4
item2.sep,item5.sep . . .
item4.sep,item2.sep . . .
item1.sep,item3.sep . . .
item2.sep,item5.sep . . .
item4.sep,item1.sep . .
答案 0 :(得分:2)
这是一个data.table解决方案。
library(data.table)
DT <- as.data.table(df)
DT[,Top2_Sept:=paste(names(.SD)[order(unlist(.SD),decreasing=TRUE)[1:2]],collapse=","),
.SDcols=2:6,by=group]
DT[,Top2_Oct:=paste(names(.SD)[order(unlist(.SD),decreasing=TRUE)[1:2]],collapse=","),
.SDcols=7:11,by=group]
DT[,list(group,Top2_Sept,Top2_Oct)]
# group Top2_Sept Top2_Oct
# 1: 1 item5.sep,item3.sep item2.oct,item1.oct
# 2: 2 item2.sep,item4.sep item1.oct,item5.oct
# 3: 3 item5.sep,item3.sep item3.oct,item2.oct
# 4: 4 item4.sep,item1.sep item5.oct,item1.oct
# 5: 5 item2.sep,item4.sep item4.oct,item5.oct
# 6: 6 item1.sep,item2.sep item1.oct,item2.oct
# 7: 7 item1.sep,item2.sep item1.oct,item2.oct
您的示例不太可重现,因为您在创建随机样本之前没有set.seed(...)
。如果您在开始时set.seed(1)
,则上述结果将重现。
此外,您的规则存在歧义。假设给定行的item1.sep:item5.sep
为(8,7,7,6,5)
。然后顶部项目在第一个col中,但第二个项目可以在第二个或第三个列中。你没有提出解决这个问题的规则。
答案 1 :(得分:1)
尝试
lst1 <- split(colnames(df)[-1],sub(".*\\.", '',colnames(df)[-1]))
df[paste("Top2", c("Oct", "Sept"), sep="_")] <- lapply(lst1, function(x) {
nm1 <- colnames(df[x])
apply(df[x], 1, function(.x)
toString(nm1[order(.x, decreasing=TRUE)[1:2]]))})
或者
lst1 <- lapply(month.abb[9:10], function(x)
df[grep(x, colnames(df), ignore.case=TRUE)])
nm1 <- lapply(lst1, colnames)
f1 <- function(x,y) apply(x, 1, function(.x)
toString(y[order(.x, decreasing=TRUE)[1:2]]))
df[paste('Top2', month.abb[9:10], sep="_")] <- Map(f1, lst1, nm1)