根据R中一列中的值删除几乎重复的行

时间:2017-10-05 04:28:46

标签: r dataframe

我有一个不同级别的分类群的数据框,以及一些分类群的多个来源的数据。这是数据的结构:

species <- c("species1", "species1", "species2", NA, NA, NA, "species3")
genus <- c("genus1", "genus1", "genus1", "genus2", "genus2", "genus3", "genus4")
value <- c(1:7)
source <- c("source1", "source2", "source1", "source1", "source2", "source2", "source3")
data <- cbind.data.frame(species, genus, value, source)

当一个分类有两行时,一行包含每个来源的数据,我想删除源列中值为source1的行。当一个分类单元只在表格中出现一次时,无论源列中的值如何,我都希望将其保留。因此,例如,对于物种1,genus1的分类单元,我想保留值= 2的行,对于物种列中的NA和genus = genus2的分类单元,我想保留行值= 5。

所以最终的输出表看起来像这样:

species    genus    value    source
species1   genus1   2        source2
species2   genus1   3        source1
NA         genus2   5        source2
NA         genus3   6        source2
species3   genus4   7        source3 

我可以想到做到这一点的hacky方法,但是想知道是否有更清洁的方法来做到这一点。如果这个问题已经得到解决,我会道歉 - 我不确定用什么搜索词来找到答案。谢谢你的帮助!

2 个答案:

答案 0 :(得分:1)

如果我正确理解数据和逻辑:

  • 分类群(属+种)可在表格中出现一次或两次
  • 在它们出现一次的情况下,来源可以是1,2或3
  • 在它们出现两次的情况下,来源可以是1或2
  • 如果它们出现两次,则应保留源2

因此,一种方法是按属+种分组,计算每组的行数并保留计数为2的源2,或保留计数为1的所有来源:

library(dplyr)
data %>% 
  group_by(genus, species) %>% 
  mutate(n = n()) %>% 
  filter(source == paste0("source", n) | n == 1) %>%
  ungroup() %>%
  select(-n)

   species  genus value  source
    <fctr> <fctr> <int>  <fctr>
1 species1 genus1     2 source2
2 species2 genus1     3 source1
3     <NA> genus2     5 source2
4     <NA> genus3     6 source2
5 species3 genus4     7 source3

答案 1 :(得分:0)

也许尝试传播数据:

library(tidyr)
spread.data = spread(data, key = "source", value = "value")

结果:

   species  genus source1 source2
1 species1 genus1       1       2
2 species2 genus1       3      NA
3     <NA> genus2       4       5
4     <NA> genus3      NA       6

然后是使用某种ifelse操纵的情况。以下是我使用dplyr

的方法
library(dplyr)
spread.data %>% mutate(value = ifelse(is.na(source2), source1, source2))

有三个来源,修改是根据您的首选来源嵌套几个ifelse语句......