我如何去这个问题很困惑。 说我有一个数据帧两列。 一列的数值列,以便(x)中,从所述第一,或-1(y)的另一指定某个值。 这是从一个匹配实验,其目的是看多照片是同一个人的结果。 在下面的例子中,有10张照片,但6是独特的个体。 在y列,如果存在匹配的对应的x被报告。 y为-1不匹配(可能会成为NAS)。 如果每个单独的超过2张照片,在比赛#将成为最新记录(照片1,5和7低于同一个人)。 该集团是时间段的照片是承担(组内没有匹配!)。 希望我有这个例子的权利:
x <- c(1,2,3,4,5,6,7,8,9,10)
y <- c(-1,-1,-1,-1,1,-1,1,-1,2,4)
group <- c(1,1,1,2,2,2,3,3,3,3)
DF <- data.frame(x,y,group)
我想创建一个新的变量命名独特的个体,并与每个个体单行的最终数据集(即只有6行而不是10),还包括该组的信息。 也就是说,如果一个人在所有三组,有可能是“111”的值,或者只是在第一和最后一组将是“101”。 有小费吗?
感谢您询问得到的数据集。 我实现了一个基于实际数字我给我组的解释是不好的,所以我稍微改变的结果。 奖金也将是不错的,但不是决定性的。
name <- c(1,2,3,4,6,8)
group_history <- as.character(c('111','101','100','011','010','001'))
bonus <- as.character(c('1,5,7','2,9','3','4,10','6','8'))
results_I_want <- data.frame(name,group_history,bonus)
我的话,失误较多上面固定...
使用你给的(更新)例如
x <- c(1,2,3,4,5,6,7,8,9,10)
y <- c(-1,-1,-1,-1,1,-1,1,-1,3,4)
group <- c(1,1,1,2,2,2,3,3,3,3)
DF <- data.frame(x,y,group)
使用x
和y
创建从较高的数字的映射,以降低该是同一人的数字。 请注意,名称是一个字符串,尽管它是一串数字。
bottom.df <- DF[DF$y==-1,]
mapdown.df <- DF[DF$y!=-1,]
mapdown <- c(mapdown.df$y, bottom.df$x)
names(mapdown) <- c(mapdown.df$x, bottom.df$x)
我们不知道它可能会多少次才能让一切下降到最低人数,因此必须使用while
循环。
oldx <- DF$x
newx <- mapdown[as.character(oldx)]
while(any(oldx != newx)) {
oldx = newx
newx = mapdown[as.character(oldx)]
}
其结果是它属于,名称由最低数量的组的基团。
DF$id <- unname(newx)
获取组成员更难。 使用reshape2
这一转换成宽幅(每组一列),其中列是“1”,如果有东西在一个“0”如果不是。
library("reshape2")
wide <- dcast(DF, id~group, value.var="id",
fun.aggregate=function(x){if(length(x)>0){"1"}else{"0"}})
最后,粘贴这些“0” /“1”的成员一起,让你描述的分组变量。
wide$grouping = apply(wide[,-1], 1, paste, collapse="")
结果:
> wide
id 1 2 3 grouping
1 1 1 1 1 111
2 2 1 0 0 100
3 3 1 0 1 101
4 4 0 1 1 011
5 6 0 1 0 010
6 8 0 0 1 001
没有“奖金”呢。
编辑:
获得奖金的信息,它有助于重新映射到保留一切。 如果你有很多的情况下,这可能是缓慢的。
更换oldx
/ newx
与部分:
iterx <- matrix(DF$x, ncol=1)
iterx <- cbind(iterx, mapdown[as.character(iterx[,1])])
while(any(iterx[,ncol(iterx)]!=iterx[,ncol(iterx)-1])) {
iterx <- cbind(iterx, mapdown[as.character(iterx[,ncol(iterx)])])
}
DF$id <- iterx[,ncol(iterx)]
要生成奖金的数据,那么你可以使用
bonus <- tapply(iterx[,1], iterx[,ncol(iterx)], paste, collapse=",")
wide$bonus <- bonus[as.character(wide$id)]
这使:
> wide
id 1 2 3 grouping bonus
1 1 1 1 1 111 1,5,7
2 2 1 0 0 100 2
3 3 1 0 1 101 3,9
4 4 0 1 1 011 4,10
5 6 0 1 0 010 6
6 8 0 0 1 001 8
请注意,这是不是与您的示例输出,但我不认为你的例子输出是正确的(你怎么能有一个grouping_history
的“000”?)
编辑:
现在,它同意。
奖金可变另一种解决方案
f_bonus <- function(data=df){
data_a <- subset(data,y== -1,select=x)
data_a$pos <- seq(nrow(data_a))
data_b <- subset(df,y!= -1,select=c(x,y))
data_b$pos <- match(data_b$y, data_a$x)
data_t <- rbind(data_a,data_b[-2])
data_t <- with(data_t,tapply(x,pos,paste,sep="",collapse=","))
return(data_t)
}