R 查找包含所有元素但不重叠的组
我得到了一组国家组,我试图得到一组相互排斥的地区,这样我可以比较它们。问题是我的数据包含多个组,其中许多组重叠。我如何才能得到一组包含所有国家但彼此不重叠的组 例如,假设这是世界上的国家列表:R 查找包含所有元素但不重叠的组,r,R,我得到了一组国家组,我试图得到一组相互排斥的地区,这样我可以比较它们。问题是我的数据包含多个组,其中许多组重叠。我如何才能得到一组包含所有国家但彼此不重叠的组 例如,假设这是世界上的国家列表: World <- c("Angola", "France", "Germany", "Australia", "New Zealand") World1)如果您只想消除重复元素,请使用!重复(…)如图所示。没有使用任何软件包 subset(df, !duplicated(element)) 给予
World <- c("Angola", "France", "Germany", "Australia", "New Zealand")
World1)如果您只想消除重复元素,请使用!重复(…)
如图所示。没有使用任何软件包
subset(df, !duplicated(element))
给予:
group element
1 Africa Angola
2 Europe France
3 Europe Germany
5 Oceania Australia
6 Oceania New Zealand
group element
1 Africa Angola
2 Europe France
3 Europe Germany
5 Oceania Australia
6 Oceania New Zealand
group element
1 Africa Angola
2 Europe France
3 Europe Germany
5 Oceania Australia
6 Oceania New Zealand
group element
1 Africa Angola
3 Europe Germany
4 Europe France
5 Oceania Australia
6 Oceania New Zealand
2)设置分区如果每个组必须完全进入或完全退出,并且每个元素只能出现一次,则这是一个设置分区问题:
library(lpSolve)
const.mat <- with(df, table(element, group))
obj <- rep(1L, ncol(const.mat))
res <- lp("min", obj, const.mat, "=", 1L, all.bin = TRUE)
subset(df, group %in% colnames(const.mat[, res$solution == 1]))
<强> 3)集合覆盖>当然,可能没有精确的集合划分,因此我们可以考虑集合覆盖问题(同一代码ExePePT)=“被替换”> =“在LP行。
library(lpSolve)
const.mat <- with(df, table(element, group))
obj <- rep(1L, ncol(const.mat))
res <- lp("min", obj, const.mat, ">=", 1L, all.bin = TRUE)
subset(df, group %in% colnames(const.mat[, res$solution == 1]))
然后,我们可以选择应用(1)删除封面中的任何副本
4)非支配组另一种方法是删除其元素构成其他组元素严格子集的任何组。例如,西欧的每个元素都在欧洲,欧洲的元素比西欧多,因此西欧元素是欧洲元素的严格子集,我们去掉了西欧。使用上面的const.mat
:
# returns TRUE if jth column of const.mat is dominated by some other column
is_dom_fun <- function(j) any(apply(const.mat[, j] <= const.mat[, -j], 2, all) &
sum(const.mat[, j]) < colSums(const.mat[, -j]))
is_dom <- sapply(seq_len(ncol(const.mat)), is_dom_fun)
subset(df, group %in% colnames(const.mat)[!is_dom])
如果有任何重复的元素,我们可以使用(1)删除它们。1)如果您想简单地消除重复元素,请使用!重复(…)
如图所示。没有使用任何软件包
subset(df, !duplicated(element))
给予:
group element
1 Africa Angola
2 Europe France
3 Europe Germany
5 Oceania Australia
6 Oceania New Zealand
group element
1 Africa Angola
2 Europe France
3 Europe Germany
5 Oceania Australia
6 Oceania New Zealand
group element
1 Africa Angola
2 Europe France
3 Europe Germany
5 Oceania Australia
6 Oceania New Zealand
group element
1 Africa Angola
3 Europe Germany
4 Europe France
5 Oceania Australia
6 Oceania New Zealand
2)设置分区如果每个组必须完全进入或完全退出,并且每个元素只能出现一次,则这是一个设置分区问题:
library(lpSolve)
const.mat <- with(df, table(element, group))
obj <- rep(1L, ncol(const.mat))
res <- lp("min", obj, const.mat, "=", 1L, all.bin = TRUE)
subset(df, group %in% colnames(const.mat[, res$solution == 1]))
<强> 3)集合覆盖>当然,可能没有精确的集合划分,因此我们可以考虑集合覆盖问题(同一代码ExePePT)=“被替换”> =“在LP行。
library(lpSolve)
const.mat <- with(df, table(element, group))
obj <- rep(1L, ncol(const.mat))
res <- lp("min", obj, const.mat, ">=", 1L, all.bin = TRUE)
subset(df, group %in% colnames(const.mat[, res$solution == 1]))
然后,我们可以选择应用(1)删除封面中的任何副本
4)非支配组另一种方法是删除其元素构成其他组元素严格子集的任何组。例如,西欧的每个元素都在欧洲,欧洲的元素比西欧多,因此西欧元素是欧洲元素的严格子集,我们去掉了西欧。使用上面的const.mat
:
# returns TRUE if jth column of const.mat is dominated by some other column
is_dom_fun <- function(j) any(apply(const.mat[, j] <= const.mat[, -j], 2, all) &
sum(const.mat[, j]) < colSums(const.mat[, -j]))
is_dom <- sapply(seq_len(ncol(const.mat)), is_dom_fun)
subset(df, group %in% colnames(const.mat)[!is_dom])
如果还有任何重复项,我们可以使用(1)来删除它们。这里有一个选项带有数据。表
library(data.table)
setDT(df)[, head(.SD, 1), element]
library(dplyr)
df %>% distinct(element, .keep_all=TRUE)
group element
1 Africa Angola
2 Europe France
3 Europe Germany
4 Oceania Australia
5 Oceania New Zealand
或使用unique
unique(setDT(df), by = 'element')
# group element
#1: Africa Angola
#2: Europe France
#3: Europe Germany
#4: Oceania Australia
#5: Oceania New Zealand
使用了包,它是数据。表这里有一个带有数据的选项。表
library(data.table)
setDT(df)[, head(.SD, 1), element]
library(dplyr)
df %>% distinct(element, .keep_all=TRUE)
group element
1 Africa Angola
2 Europe France
3 Europe Germany
4 Oceania Australia
5 Oceania New Zealand
或使用unique
unique(setDT(df), by = 'element')
# group element
#1: Africa Angola
#2: Europe France
#3: Europe Germany
#4: Oceania Australia
#5: Oceania New Zealand
使用包,它是数据。表
library(data.table)
setDT(df)[, head(.SD, 1), element]
library(dplyr)
df %>% distinct(element, .keep_all=TRUE)
group element
1 Africa Angola
2 Europe France
3 Europe Germany
4 Oceania Australia
5 Oceania New Zealand
向阿克斯曼大喊,因为他用这个回答打败了我
更新
你的问题不明确。为什么“欧洲”比“西欧”更受欢迎?换句话说,每个国家都被分配了几个小组。你想把它减少到每个国家一组。你如何决定哪一组
有一种方法,我们总是喜欢最大的:
groups <- df %>% count(group)
df %>% inner_join(groups, by='group') %>%
arrange(desc(n)) %>% distinct(elemenet, .keep_all=TRUE)
group element n
1 Europe France 2
2 Europe Germany 2
3 Oceania Australia 2
4 Oceania New Zealand 2
5 Africa Angola 1
组百分比计数(组)
df%>%内部联接(组,由class='group')%>%
排列(desc(n))%>%distinct(elemenet,.keep_all=TRUE)
群元素n
1欧洲法国2
2欧洲德国2
3大洋洲澳大利亚2
4大洋洲新西兰2
5非洲安哥拉1
向阿克斯曼大喊,因为他用这个回答打败了我
更新
你的问题不明确。为什么“欧洲”比“西欧”更受欢迎?换句话说,每个国家都被分配了几个小组。你想把它减少到每个国家一组。你如何决定哪一组
有一种方法,我们总是喜欢最大的:
groups <- df %>% count(group)
df %>% inner_join(groups, by='group') %>%
arrange(desc(n)) %>% distinct(elemenet, .keep_all=TRUE)
group element n
1 Europe France 2
2 Europe Germany 2
3 Oceania Australia 2
4 Oceania New Zealand 2
5 Africa Angola 1
组百分比计数(组)
df%>%内部联接(组,由class='group')%>%
排列(desc(n))%>%distinct(elemenet,.keep_all=TRUE)
群元素n
1欧洲法国2
2欧洲德国2
3大洋洲澳大利亚2
4大洋洲新西兰2
5非洲安哥拉1
一个可能的规则是尽量减少组的数量,例如,将一个元素与包含最多元素的组相关联
library(data.table)
setDT(df)[, n.elements := .N, by = group][
order(-n.elements), .(group = group[1L]), by = element]
解释
返回
现在,通过减少元素数量对行进行排序,并为每个国家选择第一个,即“最大”组。这应根据要求为每个国家返回一个组。
如果是并列关系,即一个组包含相同数量的元素,您可以在排序时添加额外的citeria,例如组名的长度,或仅按字母顺序排列。一个可能的规则是尽量减少组的数量,例如将元素与包含最多元素的组相关联
library(data.table)
setDT(df)[, n.elements := .N, by = group][
order(-n.elements), .(group = group[1L]), by = element]
解释
返回
现在,通过减少元素数量对行进行排序,并为每个国家选择第一个,即“最大”组。这应根据要求为每个国家返回一个组。
如果是并列关系,即一个组包含相同数量的元素,您可以在排序时添加额外的citeria,例如组名的长度,或者只是按字母顺序。一种完全不同的方法是忽略给定的群体,而只在或文件包中提供的联合国区域目录中查找国家名称
countrycodes
软件包似乎提供了更简单的界面,它还警告在其数据库中找不到的国家名称:
# given country names - note the deliberately misspelled last entry
World <- c("Angola", "France", "Germany", "Australia", "New Zealand", "New Sealand")
# regions
countrycode::countrycode(World, "country.name.en", "region")
另一种完全不同的做法是,忽略特定的群体,而只查找联合国区域目录中的国家名称,这些国家名称可以在or文件包中找到
countrycodes
软件包似乎提供了一个更简单的界面,它还警告可能出现错误的国家名称