5

我有一个类似于以下的data.frame:

df <- data.frame(population = c("AA","AA","AA","BB","BB","CC","CC","CC"),
                 individual = c("A1","A2","A3","B1","B2","C1","C2","C3"),
                 Haplotype1 = rep(1:4,2),
                 Haplotype2 = rep(5:8,2))
 > df
  population individual Haplotype1 Haplotype2
1         AA         A1          1          5
2         AA         A2          2          6
3         AA         A3          3          7
4         BB         B1          4          8
5         BB         B2          1          5
6         CC         C1          2          6
7         CC         C2          3          7
8         CC         C3          4          8

我想创建一个新数据集,其中从数据集中省略任何由少于指定数量的个体组成的人口。例如,我想仅重新分析具有三个或更多个体的人群的数据。以下是我想要的数据集:

> df <- df[!df$population=="BB",]
> df
  population individual Haplotype1 Haplotype2
1         AA         A1          1          5
2         AA         A2          2          6
3         AA         A3          3          7
6         CC         C1          2          6
7         CC         C2          3          7
8         CC         C3          4          8

但是,我有 400 个种群,大小从 5 到 155 不等,手动按名称挑选种群是不可行的。我想写一个函数,我本质上说“给我一个包含 X 个或更多个体的所有人口的数据集,并删除那些少于 X 的人。” 任何帮助或反馈表示赞赏。

4

3 回答 3

4

这应该可以解决问题:

tab <- table(df$population) > 2
df[df$population %in% names(tab)[tab], ]

#   population individual Haplotype1 Haplotype2
# 1         AA         A1          1          5
# 2         AA         A2          2          6
# 3         AA         A3          3          7
# 6         CC         C1          2          6
# 7         CC         C2          3          7
# 8         CC         C3          4          8
于 2012-10-25T14:02:47.857 回答
3

我能想到的最直接的方法是使用data.table()“data.table”包:

library(data.table)
DT <- data.table(population = c("AA","AA","AA","BB","BB","CC","CC","CC"),
                 individual = c("A1","A2","A3","B1","B2","C1","C2","C3"),
                 Haplotype1 = rep(1:4,2), Haplotype2 = rep(5:8,2),
                 key = "population")
## Or, convert your existing data.frame "df" to data.table:
## DT <- data.table(df, key = "population")
DT[, .SD[length(unique(individual)) >= 3], by = key(DT)]
#    population individual Haplotype1 Haplotype2
# 1:         AA         A1          1          5
# 2:         AA         A2          2          6
# 3:         AA         A3          3          7
# 4:         CC         C1          2          6
# 5:         CC         C2          3          7
# 6:         CC         C3          4          8

更新

我不确定这对您是否重要,但请注意,对于 Tyler 和 Sven 当前的解决方案,尽管根据您发布的问题中的数据输出是正确的,但实际上存在一些潜在的有缺陷的想法.

我写“潜在地”是因为您提到您正在寻找df$population有三个或更多个人(来自 )的组(来自df$individual)。但是,他们的两种解决方案目前都只关注人口的长度,而根据您的实际问题,我会假设您需要人口提到的唯一个体的数量。

这是一个简单的例子。使用您原来的“df”,将第 3 行中的个人更改为“A2”(df[3, 2] <- "A2")。现在,根据您在问题中的标准,只population == "CC"应返回带有的行。

如果您的数据已经只有独特的个人,那么没问题 - 但我想我会提到它;)


考虑到此逻辑的基本 R 解决方案是:

uniqueIndividuals <- ave(as.character(df$individual), 
                         df$population, FUN = function(x) length(unique(x)))
df[which(as.numeric(uniqueIndividuals) >= 3), ]
于 2012-10-25T16:40:27.690 回答
3

这也可以:

lens <- tapply(df$population , df$population, length)
df[df$population %in% names(lens)[lens > 2], ]

编辑:根据 mrdwab 的敏锐阅读,我已经编辑了我的答案。我必须承认我只查看了输入和输出:

lens <- tapply(df$individual, df$population, function(x) length(unique(x)))
df[df$population %in% names(lens)[lens > 2], ]
于 2012-10-25T14:07:12.923 回答