R根据分层数据中的儿子删除父亲行
R delete fathers row based on sons in hierarchycal data
我正在处理像这样的一些数据:
id <- c(1,1,1,2,2,2,3,3,3,4,4) # fathers
name <- c('a','b','k','b','e','g','e','f','k','f','u') # sons
data <- data.frame(id,name)
data
> data
id name
1 1 a
2 1 b
3 1 k
4 2 b
5 2 e
6 2 g
7 3 e
8 3 f
9 3 k
10 4 f
11 4 u
我的目标是:如果只有一个我不想要的儿子,删除所有与不喜欢的儿子相同父亲的行。比如我不喜欢儿子e
,结果应该是:
> data_e
id name
1 1 a
2 1 b
3 1 k
# 4 2 b
# 5 2 e
# 6 2 g
# 7 3 e
# 8 3 f
# 9 3 k
10 4 f
11 4 u
因为 id 为 2 和 3 的行的名称为 e。
这也可以是像“我不喜欢 e
和 f
在一起”这样的任务:
> data_eandf
id name
1 1 a
2 1 b
3 1 k
4 2 b
5 2 e
6 2 g
# 7 3 e
# 8 3 f
# 9 3 k
10 4 f
11 4 u
或者,"I don't want you if you have e
or f
":
> data_eorf
id name
1 1 a
2 1 b
3 1 k
# 4 2 b
# 5 2 e
# 6 2 g
# 7 3 e
# 8 3 f
# 9 3 k
# 10 4 f
# 11 4 u
如您所见,更清楚地说,我已经 "commented" 了必须删除的行。
我已经搜索过,但我发现很多问题仅基于一列,例如 data[which(data$name=='e'),]
,但这只会在儿子级别删除,而不是亲属父亲的所有行。
我还想过将数据放在宽格式中,将 id 的所有名称粘贴到一个唯一的单元格中,如果有 e,例如使用 grepl()
之类的函数,则获取,但我认为这可能是大型数据集的问题(这些数据是一个例子)。
你知道如何管理这个吗?
提前致谢
data[!(data$id %in% unique(data[data$name == 'e', 'id'])),]
unique(data[data$name == 'e', 'id']) 将获得名称字段中具有 'e' 的唯一 ID。然后您可以使用 %in% 运算符查找具有这些 ID 的所有行。这 !是一个否定运算符。
我有一个data.table解决方案
require(data.table)
id <- c(1,1,1,2,2,2,3,3,3,4,4) # fathers
name <- c('a','b','k','b','e','g','e','f','k','f','u') # sons
data <- data.table(id,name)
# names to be deleted
to_del <- c("e","f")
# returns only id's without any of the names to be deleted
data[ , .SD[ !any(name %in% to_del) ,name ] , by = "id"]
id V1
1: 1 a
2: 1 b
3: 1 k
这是一个处理不同情况的函数
dislike1 <- c('e')
dislike2 <- c('e', 'f')
myfun <- function(df, dislike, ops = NULL) {
require(dplyr)
if (is.null(ops) || ops == 'OR') {
df %>%
group_by(id) %>%
filter(!any(name %in% dislike)) %>%
ungroup
} else if (ops == 'AND') {
df %>%
group_by(id) %>%
filter(!all(dislike %in% name)) %>%
ungroup
}
}
myfun(data, dislike1)
# A tibble: 5 x 2
# id name
# <dbl> <fct>
# 1 1 a
# 2 1 b
# 3 1 k
# 4 4 f
# 5 4 u
myfun(data, dislike2, 'AND')
# A tibble: 8 x 2
# id name
# <dbl> <fct>
# 1 1 a
# 2 1 b
# 3 1 k
# 4 2 b
# 5 2 e
# 6 2 g
# 7 4 f
# 8 4 u
myfun(data, dislike2, 'OR')
# A tibble: 3 x 2
# id name
# <dbl> <fct>
# 1 1 a
# 2 1 b
# 3 1 k
我正在处理像这样的一些数据:
id <- c(1,1,1,2,2,2,3,3,3,4,4) # fathers
name <- c('a','b','k','b','e','g','e','f','k','f','u') # sons
data <- data.frame(id,name)
data
> data
id name
1 1 a
2 1 b
3 1 k
4 2 b
5 2 e
6 2 g
7 3 e
8 3 f
9 3 k
10 4 f
11 4 u
我的目标是:如果只有一个我不想要的儿子,删除所有与不喜欢的儿子相同父亲的行。比如我不喜欢儿子e
,结果应该是:
> data_e
id name
1 1 a
2 1 b
3 1 k
# 4 2 b
# 5 2 e
# 6 2 g
# 7 3 e
# 8 3 f
# 9 3 k
10 4 f
11 4 u
因为 id 为 2 和 3 的行的名称为 e。
这也可以是像“我不喜欢 e
和 f
在一起”这样的任务:
> data_eandf
id name
1 1 a
2 1 b
3 1 k
4 2 b
5 2 e
6 2 g
# 7 3 e
# 8 3 f
# 9 3 k
10 4 f
11 4 u
或者,"I don't want you if you have e
or f
":
> data_eorf
id name
1 1 a
2 1 b
3 1 k
# 4 2 b
# 5 2 e
# 6 2 g
# 7 3 e
# 8 3 f
# 9 3 k
# 10 4 f
# 11 4 u
如您所见,更清楚地说,我已经 "commented" 了必须删除的行。
我已经搜索过,但我发现很多问题仅基于一列,例如 data[which(data$name=='e'),]
,但这只会在儿子级别删除,而不是亲属父亲的所有行。
我还想过将数据放在宽格式中,将 id 的所有名称粘贴到一个唯一的单元格中,如果有 e,例如使用 grepl()
之类的函数,则获取,但我认为这可能是大型数据集的问题(这些数据是一个例子)。
你知道如何管理这个吗?
提前致谢
data[!(data$id %in% unique(data[data$name == 'e', 'id'])),]
unique(data[data$name == 'e', 'id']) 将获得名称字段中具有 'e' 的唯一 ID。然后您可以使用 %in% 运算符查找具有这些 ID 的所有行。这 !是一个否定运算符。
我有一个data.table解决方案
require(data.table)
id <- c(1,1,1,2,2,2,3,3,3,4,4) # fathers
name <- c('a','b','k','b','e','g','e','f','k','f','u') # sons
data <- data.table(id,name)
# names to be deleted
to_del <- c("e","f")
# returns only id's without any of the names to be deleted
data[ , .SD[ !any(name %in% to_del) ,name ] , by = "id"]
id V1
1: 1 a
2: 1 b
3: 1 k
这是一个处理不同情况的函数
dislike1 <- c('e')
dislike2 <- c('e', 'f')
myfun <- function(df, dislike, ops = NULL) {
require(dplyr)
if (is.null(ops) || ops == 'OR') {
df %>%
group_by(id) %>%
filter(!any(name %in% dislike)) %>%
ungroup
} else if (ops == 'AND') {
df %>%
group_by(id) %>%
filter(!all(dislike %in% name)) %>%
ungroup
}
}
myfun(data, dislike1)
# A tibble: 5 x 2
# id name
# <dbl> <fct>
# 1 1 a
# 2 1 b
# 3 1 k
# 4 4 f
# 5 4 u
myfun(data, dislike2, 'AND')
# A tibble: 8 x 2
# id name
# <dbl> <fct>
# 1 1 a
# 2 1 b
# 3 1 k
# 4 2 b
# 5 2 e
# 6 2 g
# 7 4 f
# 8 4 u
myfun(data, dislike2, 'OR')
# A tibble: 3 x 2
# id name
# <dbl> <fct>
# 1 1 a
# 2 1 b
# 3 1 k