提问人:SJSU2013 提问时间:11/26/2013 最后编辑:HenrikSJSU2013 更新时间:11/8/2020 访问量:28303
基于每组行数的子集数据框
Subset data frame based on number of rows per group
问:
我有这样的数据,其中某些“名称”出现三次以上:
df <- data.frame(name = c("a", "a", "a", "b", "b", "c", "c", "c", "c"), x = 1:9)
name x
1 a 1
2 a 2
3 a 3
4 b 4
5 b 5
6 c 6
7 c 7
8 c 8
9 c 9
我希望根据变量每个级别的行数(观测值)对数据进行子集(过滤)。如果某个级别的出现次数超过 3 次,我想删除属于该级别的所有行。因此,在此示例中,我们将删除 ,因为该组中有行:name
name
name == c
> 3
name x
1 a 1
2 a 2
3 a 3
4 b 4
5 b 5
我写了这段代码,但无法让它工作。
as.data.frame(table(unique(df)$name))
subset(df, name > 3)
答:
62赞
Henrik
11/26/2013
#1
首先,有两种选择。一个依赖于 ,另一个依赖于 和。然后,两种方式。base
table
ave
length
data.table
1.table
tt <- table(df$name)
df2 <- subset(df, name %in% names(tt[tt < 3]))
# or
df2 <- df[df$name %in% names(tt[tt < 3]), ]
如果您想逐步完成它:
# count each 'name', assign result to an object 'tt'
tt <- table(df$name)
# which 'name' in 'tt' occur more than three times?
# Result is a logical vector that can be used to subset the table 'tt'
tt < 3
# from the table, select 'name' that occur < 3 times
tt[tt < 3]
# ...their names
names(tt[tt < 3])
# rows of 'name' in the data frame that matches "the < 3 names"
# the result is a logical vector that can be used to subset the data frame 'df'
df$name %in% names(tt[tt < 3])
# subset data frame by a logical vector
# 'TRUE' rows are kept, 'FALSE' rows are removed.
# assign the result to a data frame with a new name
df2 <- subset(df, name %in% names(tt[tt < 3]))
# or
df2 <- df[df$name %in% names(tt[tt < 3]), ]
2. 以及ave
length
正如@flodel所建议的:
df[ave(df$x, df$name, FUN = length) < 3, ]
3. : 和 :data.table
.N
.SD
library(data.table)
setDT(df)[, if (.N < 3) .SD, by = name]
4. : 和 :data.table
.N
.I
setDT(df)
df[df[, .I[.N < 3], name]$V1]
另请参阅相关的问答:计算每组的观测值/行数,并将结果添加到数据框。
48赞
Joe
10/18/2016
#2
使用软件包:dplyr
df %>%
group_by(name) %>%
filter(n() < 4)
# A tibble: 5 x 2
# Groups: name [2]
name x
<fct> <int>
1 a 1
2 a 2
3 a 3
4 b 4
5 b 5
n()
返回当前组中的观测值数,因此我们可以命名,然后仅保留属于该组中行数小于 4 的组的行。group_by
4赞
Cettt
10/11/2019
#3
使用包的另一种方法是使用该函数,然后在原始数据帧上执行半连接:dpylr
count
library(dplyr)
df %>%
count(name) %>%
filter(n <= 3) %>%
semi_join(df, ., by = "name")
1赞
Karolis Koncevičius
11/8/2020
#4
软件包 “inops” 有一些有用的中缀运算符。对于这种特殊情况,操作员可以根据元素出现的次数来选择元素。%in#%
library(inops)
df[df$name %in#% 1:3,]
返回:
name x
1 a 1
2 a 2
3 a 3
4 b 4
5 b 5
此处仅返回出现 1 次、2 次或 3 次的元素。相反,如果我们想选择出现 4 次的元素,我们会这样做:df$name %in#% 1:3
TRUE
df[df$name %in#% 4,]
结果如下:
name x
6 c 6
7 c 7
8 c 8
9 c 9
上一个:如何在R包中找到所有函数?
下一个:将数据从 R 导出到 Excel
评论