r为给定列中的每个值返回公共行

r为给定列中的每个值返回公共行,r,dataframe,set-operations,R,Dataframe,Set Operations,假设我有这样一个数据帧: category type [1] A green [2] A purple [3] A orange [4] B yellow [5] B green [6] B orange [7] C green 如何获得包含每个类别中出现的类型的列表?在这种情况下,它应该如下所示: type [1] green 我知道这个问题很基本,可能以前有人问过;但是我的

假设我有这样一个数据帧:

    category  type
[1] A        green
[2] A        purple
[3] A        orange
[4] B        yellow
[5] B        green
[6] B        orange
[7] C        green
如何获得包含每个类别中出现的类型的列表?在这种情况下,它应该如下所示:

    type
[1] green
我知道这个问题很基本,可能以前有人问过;但是我的方法太长了,我相信有一种更有效的方法可以做到这一点:我过去常常根据类别分割数据帧,然后进行集合交集。请问有更好的办法吗?谢谢

这里有一种使用data.table的方法-假设每个类别最多只显示一次类型:

library(data.table)
DT <- data.table(DF)
##
R> DT[
    ,list(
      nCat=.N
    ),by=type][
      nCat==length(unique(DT$category)),
      type]
[1] "green"
如果不能保证每个类别最多只显示一次该类型,请对上述内容稍作修改:

R> DT[
    ,list(
      nCat=length(unique(category))
    ),by=type][
      nCat==length(unique(DT$category)),
      type]
[1] "green" 
数据:


我真的找不到一个非常明显的解决方案,但这确实有效

df <- data.frame(category=c("A", "A", "A", "B", "B", "B", "C"), 
                 type=c("green", "purple", "orange", "yellow", 
                        "green", "orange", "green"))

# Split the data frame by type
# This gives a list with elements corresponding to each type
types <- split(df, df$type)

# Find the length of each element of the list
len <- sapply(types, function(t){length(t$type)})

# If the length is equal to the number of categories then 
# the type is present in all categories 
res <- names(which(len==length(unique(df$category))))
请注意,sapply将返回类型作为向量的名称,因此在下一条语句中调用名称。

如果df是data.frame,则由于Reduce,下面是一行代码:

假设类别中最多出现一次类型,否则将==更改为>=并使用表,您可以尝试以下操作:

 colnames(table(df))[colSums(table(df)) == length(unique(df$category))]
[1] "green"

一种方法是制作一个表格,或者选择出现的类型,每个类别出现的次数在本例中为3,或者因为您说它只能出现一次,所以只需取平均值并选择平均值==1或>=1

dat <- read.table(header = TRUE, text="category  type
A        green
A        purple
A        orange
B        yellow
B        green
B        orange
C        green")

tbl <- data.frame(with(dat, ftable(category, type)))
tbl[with(tbl, ave(Freq, type)) >= 1, ]

#   category  type Freq
# 1        A green    1
# 2        B green    1
# 3        C green    1

unique(tbl[with(tbl, ave(Freq, type)) >= 1, 'type'])
# [1] green
假设您的数据为df格式:


这将计算每种类型中出现的次数,并查看哪些出现的次数与您的类别相同。如果类型在一个类别中出现不超过一次,它将有效地执行您想要的操作,但如果违反该假设,它将不起作用。

您知道类别的数量,并且类型在一个类别中出现不止一次的可能性吗?从上面的示例中,您知道绿色会出现在每个类别中,因为它出现了3次,但我不确定这是否适用于您的实际数据。@Joe我保证某个类型在任何给定类别中不会出现超过一次,以便为不懂data.table语法的人解释代码。@nico Yes,很抱歉,我在你的评论中扩展了我的答案。很好!另一种方法是:uniquedt[,.N,by=type][N==uniqueNdt$category,type]。uniqueN是1.9.5中的新版本,它是lengthunique的更快版本。@Arun谢谢!我现在使用的机器有一个旧版本的R/data.table,但我肯定会在我的另一台计算机上使用它。嗨,col,请问reduce函数在哪个软件包中?谢谢这是基地R:不错+1如果你添加一些解释。嗨,乔,请问聚合函数的包是什么?谢谢@maryam它是默认加载的,它来自stats包。我怎么知道?在R中输入?聚合。如果它没有产生任何结果,我可以尝试??聚合,如果这不起作用,也可以rsitesearchaggrate!
x = df$category
y = df$type

Reduce(intersect, lapply(unique(x), function(u) y[x==u]))
#[1] "green"
 colnames(table(df))[colSums(table(df)) == length(unique(df$category))]
[1] "green"
dat <- read.table(header = TRUE, text="category  type
A        green
A        purple
A        orange
B        yellow
B        green
B        orange
C        green")

tbl <- data.frame(with(dat, ftable(category, type)))
tbl[with(tbl, ave(Freq, type)) >= 1, ]

#   category  type Freq
# 1        A green    1
# 2        B green    1
# 3        C green    1

unique(tbl[with(tbl, ave(Freq, type)) >= 1, 'type'])
# [1] green
df.sum <- aggregate(df$tpye, by = list(df$type), FUN = length)
types <- df.sum[which(df$sum == length(unique(df$x))),]