在数据集中查找匹配的对(或记录)

时间:2017-05-05 17:44:20

标签: r dataframe dplyr

我有一个巨大的数据集,我需要根据一些标准匹配样本。例如,对于某个地点和自治市镇的每个电影明星,找到两个不是电影明星的人(随机)。电影明星为1,非电影明星为0。

 location<- c('manhattan', 'manhattan' ,'manhattan', 'manhattan', 'manhattan', 'manhattan')
 moviestar<- c(0,1,0,0,0,1)
 id<- c(1,2,3,4,5,6)
 borough <- c('williamsburg', 'williamsburg', 'williamsburg', 'williamsburg', 'williamsburg','williamsburg')

  df<- data.frame(location,moviestar, borough)

我想要创建一个子集,该子集具有匹配的电影明星对与居住在同一位置和行政区的另外两个非电影明星(随机挑选)。有什么建议吗?基本上有6个人住在曼哈顿,有两颗星住在曼哈顿,我想匹配每颗星,在这种情况下,2和6是星星,那么我想在最终数据中配对如下:

我期待的输出是这样的,

  > subset 
  location moviestar borough       id matchpairid
  manhattan    1    williamsburg   2  match1
  manhattan    0    williamsburg   1  match1
  manhttan     0    williamsburg   5  match1
  manhattan    1    williamsburg   6  match2
  manhattan    0    williamsburg   3  match2
  manhttan     0    williamsburg   5  match2

3 个答案:

答案 0 :(得分:0)

你可以通过计算每组的电影明星和非电影明星的数量来获得这个,然后根据这个条件在每个组内进行过滤:

library(dplyr)
df %>%
  group_by(location) %>%
  mutate(num_movie_stars = sum(moviestar),
         num_non_movie_stars = sum(1 - moviestar)) %>%
  group_by(location, moviestar) %>%
  filter(moviestar & row_number() <= num_non_movie_stars / 2 |
         !moviestar & row_number() <= num_movie_stars * 2) %>%
  ungroup()

答案 1 :(得分:0)

在data.table中,您可以使用以下

执行此操作
library(data.table)

setDT(df)[df[, keeper := max(moviestar) == 1, by=.(location, borough)][(keeper),
            if(any(moviestar == 0)) c(sample(.I[moviestar == 0], 2 * sum(moviestar)),
                                             .I[moviestar == 1]), by=.(location, borough)]$V1
          ][, keeper := NULL][]

    location moviestar      borough
1: manhattan         0 williamsburg
2: manhattan         0 williamsburg
3: manhattan         1 williamsburg

守护者在自治市镇的电影明票中被指定为TRUE。然后它用于数据的子集。在第二个j语句中,检查是否有任何非电影明星。如果是,则为该行政区中的每个电影明星拍摄2行非电影明星(使用.I),还包括电影明星。 $V1提取这些索引。将其提供给原始数据集以获取结果。

keeper := NULL删除中间守护变量,最后[]打印结果。

答案 2 :(得分:0)

一个简单的无包装答案:

starstruck <- function(location, borough, df){
  subsamp <- df[which(location == df$location & borough == df$borough),]
  stars <- subsamp[subsamp$moviestar == 1,]
  nostars <- subsamp[subsamp$moviestar == 0,]
  randomcombo <- rbind(stars[sample(nrow(stars), 1, F),], 
                       nostars[sample(nrow(nostars), 2, F),])
  randomcombo[order(rownames(randomcombo)),]
}

starstruck("manhattan", "williamsburg", df)
#   location moviestar      borough
#1 manhattan         0 williamsburg
#2 manhattan         1 williamsburg
#3 manhattan         0 williamsburg