假设我有以下数据框:
df <- data.frame(year=c(2010,2011,2012,2010,2011,2010,2011,2012), company = c("a","a","a","b","b","c","c","c"))
year company
1 2010 a
2 2011 a
3 2012 a
4 2010 b
5 2011 b
6 2010 c
7 2011 c
8 2012 c
Run Code Online (Sandbox Code Playgroud)
我想找到这三年中都存在的公司。一种麻烦的方法是:
library(dplyr)
companies_2010 <- df %>% filter(year==2010) %>% select(company)
companies_2011 <- df %>% filter(year==2011) %>% select(company)
companies_2012 <- df %>% filter(year==2012) %>% select(company)
companies <- intersect(companies_2010, companies_2011) %>% intersect(., companies_2012)
company
1 a
2 c
Run Code Online (Sandbox Code Playgroud)
有没有更优雅的方法来做到这一点?
由于年份不同并且在所需的集合中,我们只需计算每个公司有多少个年份即可。(如果情况并非如此,一般来说,则应用下面的解决方案来df2 <- unique(merge(df, data.frame(year = 2010:2012)))代替 df。此外,如果我们不知道值 3 并且我们希望它等于数据中的唯一年份数,那么我们可以使用以下方法计算它length(unique(df$year))。
现在,使用这个想法有几种选择。我们可以使用 table 来获取它们的频率,然后保留频率为 3 的频率,或者在最后一种情况下,我们可以使用 dplyr 的计数,然后过滤以获得频率为 3 的频率。
tab <- table(df$company)
names(tab)[tab == 3]
## [1] "a" "c"
names(Filter(function(x) x == 3, table(df$company)))
## [1] "a" "c"
library(dplyr)
df %>%
count(company) %>%
filter(n == 3) %>%
select(company)
## company
## 1 a
## 2 c
Run Code Online (Sandbox Code Playgroud)
使用问题的相交思想按年份拆分公司,然后使用Reduce重复应用相交:
with(df, Reduce(intersect, split(company, year)))
## [1] "a" "c"
Run Code Online (Sandbox Code Playgroud)
我们可以使用这样的表格来可视化这一点。任何没有零值的列都对应于具有所有年份的公司。
table(df)
## company
## year a b c
## 2010 1 1 1
## 2011 1 1 1
## 2012 1 0 1
Run Code Online (Sandbox Code Playgroud)
或存在绿色且不存在红色的热图。任何完全绿色的柱子都有年份。
heatmap(table(df), Rowv = NA, Colv = NA, col = 2:3, scale = "none")
Run Code Online (Sandbox Code Playgroud)
ave这是带有和的基本 R 解unique。
n <- with(df, ave(year, company, FUN = length))
unique(df$company[n == 3])
#[1] "a" "c"
Run Code Online (Sandbox Code Playgroud)
既然您收到了一些出色的答案,我认为带有一点想象力的非常不同的方法也可能很好。
我将您的问题可视化为二分图,其中我们有两组不同的节点,其中一个是公司名称,另一个是年份,而公司之间以及年份之间没有联系。
library(igraph)
# Creating a graph object but first I alternate the columns of your data set
df[, c(2, 1)] |>
graph_from_data_frame() -> g
# Then we create a type object to distinguish between 2 sets of nodes, Type FALSE
# refers to company name and type TRUE refers to years
V(g)$type <- bipartite.mapping(g)$type
# Then we extract those nodes whose degree are equal to 3 while they are of type FALSE
V(g)[degree(g, V(g)) == length(unique(df$year)) & V(g)$type == FALSE]
+ 2/6 vertices, named, from c172916:
[1] a c
Run Code Online (Sandbox Code Playgroud)
如果您想查看图表的外观:
plot(g,
vertex.color = ifelse(V(g)$type, "lightblue", "salmon"),
vertex.shape = ifelse(V(g)$type, "circle", "square"),
vertex.size = 25,
edge.color = "grey",
layout = layout.bipartite)
Run Code Online (Sandbox Code Playgroud)
这通常不起作用计算任意交点,但是 (\xc2\xbf 我认为?) 会执行您上面指定的操作:
\n(df \n %>% group_by(company)\n %>% filter(all(2010:2012 %in% year))\n %>% select(company)\n %>% distinct()\n)\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
841 次 |
| 最近记录: |