示例数据:
a <- as.data.frame(matrix(list(1,1,3,4,1,1,3,4,1,1,3,4,1,1,3,4,1,1,3,4),4,5))
b1 <-c(30,40,20,15) b2<-c("A","A","B","C")
b <-as.data.frame(cbind(b1,b2))
a.b<-cbind(a,b)
初始价值:
a.b
row V1 V2 V3 V4 V5 b1 b2
1 1 1 1 1 1 30 A
2 1 1 1 1 1 40 A
3 3 3 3 3 3 20 B
4 4 4 4 4 4 15 C
我希望看到的是V1,V2,V3,V4,V5,b1与max(b1),A,B,C 应该有3行:
row V1 V2 V3 V4 V5 b1 A B C
1 1 1 1 1 1 40 2 0 0
3 3 3 3 3 3 20 0 1 0
4 4 4 4 4 4 15 0 0 1
我将如何得到它。我想到了聚合,演员和重塑,但遇到了困难。 THKS。
答案 0 :(得分:0)
这不是一件容易的事。
这是我的方法,它远非完美但它应该足以让你开始:
first_part = aggregate(a.b[,1:6],by=list(a.b$b2),
function(x) {y=as.factor(unlist(x));max(as.numeric(levels(y))[y])})
second_part = diag(by(a.b$b2,a.b$b2,function(x)length(x)))
colnames(second_part) = first_part[,1]
all = cbind(first_part[2:7], second_part)
它完成了这项工作:
> all
V1 V2 V3 V4 V5 b1 A B C
1 1 1 1 1 1 40 2 0 0
2 3 3 3 3 3 20 0 1 0
3 4 4 4 4 4 15 0 0 1
解释它的工作原理:
第一行构造矩阵的第一部分:保持行具有b1的最大值。
> first_part
Group.1 V1 V2 V3 V4 V5 b1
1 A 1 1 1 1 1 40
2 B 3 3 3 3 3 20
3 C 4 4 4 4 4 15
“警告!”这是因为这个方法是如此:它将max函数应用于具有相同字母的所有行中的所有元素。但是,如果V1 ... V5中的值不同,则未指定要执行的操作。
第二行和第三行构成矩阵的第二部分:
A B C
[1,] 2 0 0
[2,] 0 1 0
[3,] 0 0 1
总的来说,我确信有更好,更清洁的方法。如果你看到可能的改善,请发表评论,我总是很高兴学到新东西:)
答案 1 :(得分:0)
这看起来像是一个lapply(split(...))问题。未经测试,并假设您不使用as.data.frame(cbind(...))
lapply(split(df, df[2:6]), function (d){
cbind( max( d[7]), table(d[8]) )})
不使用字符比较的原因是“4”> “15”返回TRUE。