r return 给定列中每个值的公共行
r return common rows for each value in a given column
假设我有一个如下所示的数据框:
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
的一种方法 - 前提是 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,通过利用 uniqueN
函数,可以使用更新版本的 data.table
更简洁地完成此操作:
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)
我真的找不到一个非常明显的解决方案,但是这个解决了这个问题。
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
将 return 类型作为向量的名称,因此在下一个语句中调用 names
。
如果 df
是您的 data.frame
,这里是 'one' 行代码,感谢 Reduce
:
x = df$category
y = df$type
Reduce(intersect, lapply(unique(x), function(u) y[x==u]))
#[1] "green"
假设 type
在 category
中最多出现一次(否则将 ==
更改为 >=
)并使用 table
您可以尝试以下:
colnames(table(df))[colSums(table(df)) == length(unique(df$category))]
[1] "green"
一种方法是制作一个 table 和 select 出现每个类别出现次数的类型(在本例中为 3),或者因为你说它只能出现一次,取均值和select均值== 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
:
df.sum <- aggregate(df$tpye, by = list(df$type), FUN = length)
types <- df.sum[which(df$sum == length(unique(df$x))),]
这将计算每种类型的出现次数,并查看哪些出现次数与您的类别相同。如果类型在一个类别中出现的次数不超过一次,它将有效地执行您想要的操作,但如果违反该假设则它将不起作用。
假设我有一个如下所示的数据框:
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
的一种方法 - 前提是 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,通过利用 uniqueN
函数,可以使用更新版本的 data.table
更简洁地完成此操作:
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)
我真的找不到一个非常明显的解决方案,但是这个解决了这个问题。
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
将 return 类型作为向量的名称,因此在下一个语句中调用 names
。
如果 df
是您的 data.frame
,这里是 'one' 行代码,感谢 Reduce
:
x = df$category
y = df$type
Reduce(intersect, lapply(unique(x), function(u) y[x==u]))
#[1] "green"
假设 type
在 category
中最多出现一次(否则将 ==
更改为 >=
)并使用 table
您可以尝试以下:
colnames(table(df))[colSums(table(df)) == length(unique(df$category))]
[1] "green"
一种方法是制作一个 table 和 select 出现每个类别出现次数的类型(在本例中为 3),或者因为你说它只能出现一次,取均值和select均值== 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
:
df.sum <- aggregate(df$tpye, by = list(df$type), FUN = length)
types <- df.sum[which(df$sum == length(unique(df$x))),]
这将计算每种类型的出现次数,并查看哪些出现次数与您的类别相同。如果类型在一个类别中出现的次数不超过一次,它将有效地执行您想要的操作,但如果违反该假设则它将不起作用。