使用dplyr通过多行和列匹配来设置数据帧

时间:2016-09-22 22:00:24

标签: r dplyr

我已经搜索了这个问题的答案了一段时间,并没有找到这个确切的测试用例。如果在其他地方解决了,请接受我的道歉。

我从政府调查计划中获得了大量data生物观察数据(约2,500,000行,约50列)。重要的列是reg(区域),speciesyear(调查的)。

我想将数据框的子集仅包含每个地区每年至少发现一次的物种。 (我还需要为每年至少发现10次的物种做这个,但我认为解决方案是相同的。)

换句话说,我只需要过滤出species每年都存在region的行,unique(year)也存在 - 基本上,所有行species对于每个unique(year)的{​​{1}}个匹配项reg。 (只有九个区域,因此我当然可以将数据子集化为九个数据帧并重复此过滤九次,但我希望有一个更优雅的解决方案,仅使用dplyr我可以直接应用于{ {1}}。)

谢谢!

编辑:我按照@aichao的建议创建了一个模拟数据集。

data

所以在这个df中,我想只保留每次调查区域时发现的物种(让我们假装这是完整的数据)。从> year = c(1999,2000,2000,2004,2004,2008) > reg = c('ai','ci','ci','ai','ai','ci') > species = c('blueei','greenei','yellowei','blueei','greenei','yellowei') > df <- data.frame(year, reg, species) > df year reg species 1 1999 ai blueei 2 2000 ci greenei 3 2000 ci yellowei 4 2004 ai blueei 5 2004 ai greenei 6 2008 ci yellowei 开始,我想保留ai - 这是在每个调查年度中找到的 - 但不是blueei。同样,在greenei中,我希望保留ci但不保留yellowei,因为greenei在2008年没有出现。

2 个答案:

答案 0 :(得分:1)

  

仅保留每次调查该区域时发现的物种

我们可以使用dplyr执行以下操作:

library(dplyr)
result <- df %>% group_by(reg) %>% mutate(num.years.in.reg = length(unique(year))) %>% 
                 group_by(reg,species) %>% filter(length(unique(year)) == first(num.years.in.reg)) %>%
                 select(-num.years.in.reg) %>% arrange(reg)

注意:

  1. 首先,group_by reg并创建一个列num.years.in.reg,其中包含调查该地区的unique年数。
  2. 然后,group_by同时regspecies并仅保留speciesuniquespecies年的unique该地区接受调查的人数等于该地区调查的first年数。在这里,num.years.in.reg只检索num.years.in.reg中的第一个值,因为它们对于组中的所有行都是相同的。
  3. 删除result列,然后按regresult进行排序。
  4. 请注意,在过滤逻辑中,我们不需要比较唯一年份值,只需要比较唯一年份的数量,因为第二个分组是第一个分组的子集。也就是说,独特的年份将是相同的,但在第二组中可能比第一组更少。
  5. 根据您发布的数据,print(result) ##Source: local data frame [4 x 3] ##Groups: reg, species [2] ## ## year reg species ## <dbl> <chr> <chr> ##1 1999 ai blueei ##2 2004 ai blueei ##3 2000 ci yellowei ##4 2008 ci yellowei 为:

    set(OpenCV_DIR ${THIRD_PARTY_DIR}/OpenCV)
    find_package(OpenCV REQUIRED)
    ...
    add_executable(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES})
    target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
    

答案 1 :(得分:1)

您可以在原始数据框中创建一个id变量,表示区域+种类对。

 year = c(1999,2000,2000,2004,2004,2008)
 reg = c('ai','ci','ci','ai','ai','ci')
 species = c('blueei','greenei','yellowei','blueei','greenei','yellowei')

df <- data.frame(year, reg, species) %>%
 mutate(ids = paste(reg, species, sep='-'))

然后创建一个新的数据框,为每个region标识year的总数,每个year存在多少species,以及物种在所有年份都存在。

 df2 <- df %>%
 group_by(reg) %>%
 mutate(n_yrs = length(unique(year))) %>%
 group_by(reg, ids) %>%
 summarize(present_yrs = length(unique(year)),
         all_yrs     = mean(n_yrs, na.rm = T)) %>%
 filter(present_yrs == all_yrs)

最后,过滤旧数据集,使其仅包含id中的df2

filter(df, ids %in% df2$ids)