比较两列:logical-是从第1列值也列2?(Comparing two columns: log

2019-09-26 13:18发布

我如何去这个问题很困惑。 说我有一个数据帧两列。 一列的数值列,以便(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)

我的话,失误较多上面固定...

Answer 1:

使用你给的(更新)例如

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)

使用xy创建从较高的数字的映射,以降低该是同一人的数字。 请注意,名称是一个字符串,尽管它是一串数字。

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”?)

编辑:

现在,它同意。



Answer 2:

奖金可变另一种解决方案

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)
}


文章来源: Comparing two columns: logical- is value from column 1 also in column 2?
标签: r compare set