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

时间:2015-01-28 21:10:42

标签: 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

我知道这个问题是基本的,可能以前是其他人问的。但我的方法太长了,我确信这是一种更有效的方法:我曾经根据类别拆分数据帧,并进行设置交集。请问有更好的方法吗?谢谢!

6 个答案:

答案 0 :(得分:4)

假设type最多出现category一次(否则将==更改为>=)并使用table您可以尝试以下操作:

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

答案 1 :(得分:3)

以下是使用data.table的一种方法 - 前提是type每个类别最多只出现一次:

library(data.table)
DT <- data.table(DF)
##
R> DT[
    ,list(
      nCat=.N
    ),by=type][
      nCat==length(unique(DT$category)),
      type]
[1] "green"

所有这一切都将原始数据聚合为按类型(nCat)计算的行数,然后通过获取nCat等于中的唯一类别数的行来生成结果的子集DT

修改 感谢@Arun,利用data.table函数,可以使用更新版本的uniqueN更简洁地完成此操作:

unique(dt)[, .N, by=type][N == uniqueN(dt$category), type]

如果不保证每个类别最多只显示type一次,则会对上述内容进行略微修改:

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

数据:

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

答案 2 :(得分:2)

我无法找到一个非常明显的解决方案,但这可以完成这项任务。

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将返回类型作为向量的名称,因此在下一个语句中调用names

答案 3 :(得分:2)

如果dfdata.frame,则感谢Reduce,这是'一行'代码:

x = df$category
y = df$type

Reduce(intersect, lapply(unique(x), function(u) y[x==u]))
#[1] "green"

答案 4 :(得分:2)

一种方法是创建一个表,并选择出现每个类别出现次数的类型(在这种情况下为3),或者因为你说它只能出现一次,只需取平均值并选择mean == 1(或&gt; = 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

答案 5 :(得分:1)

假设您的数据位于df

df.sum <- aggregate(df$tpye, by = list(df$type), FUN = length)
types <- df.sum[which(df$sum == length(unique(df$x))),]

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