Return 根据 2 个条件在列表中重复
Return duplicates in a list based on 2 criteria
我有一个包含 2 个数据集的列表。
a = data.frame(c(1,1,1,1,1,2,2,2,2,2), c("a","b", "c", "d","e","e","f", "g", "h","i"))
colnames(a) = c("Numbers","Letters")
c = data.frame(c(3,3,3,3,3,4,4,4,4,4), c("q","r", "s", "t","u","u","v", "w", "x","y"))
colnames(c) = c("Numbers","Letters")
my.list = list(a,c)
my.list
我有兴趣只返回在每个数据集的唯一数字之间发现的共同字母。期望的结果如下:
new_a = data.frame(c(1,2),c("e","e"))
new_c = data.frame(c(3,4),c("u","u"))
colnames(new_a) = c("Numbers","Letters")
colnames(new_c) = c("Numbers","Letters")
my.new.list = list(new_a,new_c)
my.new.list
如您所见,字母 "e" 是数字“1”和“2”在数据集 1 中唯一共享的字母,而字母 "u" 是数字唯一共享的字母数据集2中的3和4.
我正在尝试对一个非常大的列表执行此操作。为了让您了解我的真正问题,我有一个列表,其中每个元素都是一个状态。在每个州内,我有多个资产经理或 "accounts",每个账户都有多个代码。我试图找到每个地理位置的帐户共有的代码。在上面的示例中,数字是帐户,字母是代码,列表中包含的两个数据集是两个不同的状态。我希望这有助于解决我的问题。
谢谢!
我们可以在 base R
中使用 Reduce
和 intersect
lapply(my.list, function(x) x[with(x, Letters %in%
Reduce(intersect, split(Letters, Numbers))),])
或使用dplyr
library(dplyr)
lapply(my.list, function(x)
x %>%
group_by(Letters) %>%
filter(n_distinct(Numbers)==2))
与其使用 list
,还可以将其更改为具有附加分组列的单个数据集,然后执行相同的操作,
library(tidyr)
unnest(my.list, group) %>%
group_by(group, Letters) %>%
filter(n_distinct(Numbers)==2)
如果我们不知道每个列表元素中唯一数字的数量
unnest(my.list, group) %>%
group_by(group) %>%
mutate(n= n_distinct(Numbers)) %>%
group_by(Letters, add=TRUE) %>%
filter(n_distinct(Numbers)==n) %>%
select(-n)
library(data.table)
a <- as.data.table(a)
a[, if(.N > 1) .SD, by = list(Letters)]
# Letters Numbers
# 1: e 1
# 2: e 2
解释:取 table a
并按列 Letters
(by = list(Letters)
) 和 return 分组,每个组的数据子集 (.SD
) 仅当 that 组的行数 (.N
) >1 时。
我有一个包含 2 个数据集的列表。
a = data.frame(c(1,1,1,1,1,2,2,2,2,2), c("a","b", "c", "d","e","e","f", "g", "h","i"))
colnames(a) = c("Numbers","Letters")
c = data.frame(c(3,3,3,3,3,4,4,4,4,4), c("q","r", "s", "t","u","u","v", "w", "x","y"))
colnames(c) = c("Numbers","Letters")
my.list = list(a,c)
my.list
我有兴趣只返回在每个数据集的唯一数字之间发现的共同字母。期望的结果如下:
new_a = data.frame(c(1,2),c("e","e"))
new_c = data.frame(c(3,4),c("u","u"))
colnames(new_a) = c("Numbers","Letters")
colnames(new_c) = c("Numbers","Letters")
my.new.list = list(new_a,new_c)
my.new.list
如您所见,字母 "e" 是数字“1”和“2”在数据集 1 中唯一共享的字母,而字母 "u" 是数字唯一共享的字母数据集2中的3和4.
我正在尝试对一个非常大的列表执行此操作。为了让您了解我的真正问题,我有一个列表,其中每个元素都是一个状态。在每个州内,我有多个资产经理或 "accounts",每个账户都有多个代码。我试图找到每个地理位置的帐户共有的代码。在上面的示例中,数字是帐户,字母是代码,列表中包含的两个数据集是两个不同的状态。我希望这有助于解决我的问题。
谢谢!
我们可以在 base R
Reduce
和 intersect
lapply(my.list, function(x) x[with(x, Letters %in%
Reduce(intersect, split(Letters, Numbers))),])
或使用dplyr
library(dplyr)
lapply(my.list, function(x)
x %>%
group_by(Letters) %>%
filter(n_distinct(Numbers)==2))
与其使用 list
,还可以将其更改为具有附加分组列的单个数据集,然后执行相同的操作,
library(tidyr)
unnest(my.list, group) %>%
group_by(group, Letters) %>%
filter(n_distinct(Numbers)==2)
如果我们不知道每个列表元素中唯一数字的数量
unnest(my.list, group) %>%
group_by(group) %>%
mutate(n= n_distinct(Numbers)) %>%
group_by(Letters, add=TRUE) %>%
filter(n_distinct(Numbers)==n) %>%
select(-n)
library(data.table)
a <- as.data.table(a)
a[, if(.N > 1) .SD, by = list(Letters)]
# Letters Numbers
# 1: e 1
# 2: e 2
解释:取 table a
并按列 Letters
(by = list(Letters)
) 和 return 分组,每个组的数据子集 (.SD
) 仅当 that 组的行数 (.N
) >1 时。