R根据分层数据中的子行删除父行

R根据分层数据中的子行删除父行,r,dataframe,hierarchical-data,R,Dataframe,Hierarchical 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

我正在处理以下数据:

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
因为id为2和3的行的名称中有e
这也可能是一项类似“我不喜欢把
e
f
放在一起”的任务:

或者,“如果你有
e
f
,我不想要你”:

正如您所注意到的,更清楚地说,我已经“注释”了必须删除的行

我已经搜索过了,但是我发现很多问题都是基于一个列的,比如
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的行。这个是一个否定运算符


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
require(data.table)

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
require(data.table)

id这里有一个函数来处理不同的情况

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    
不喜欢1%
解组
}else if(ops=='和'){
df%>%
分组依据(id)%>%
筛选器(!全部(不喜欢%name中的%1))%>%
解组
}
}
myfun(数据,不喜欢1)
#一个tibble:5x2
#身份证名称
#  
#11A
#21 b
#31K
#4楼
#54U
myfun(数据,不喜欢2,'和')
#一个tibble:8x2
#身份证名称
#  
#11A
#21 b
#31K
#4.2 b
#5.2 e
#6.2克
#7.4楼
#84U
myfun(数据,不喜欢2“或”)
#一个tibble:3x2
#身份证名称
#  
#11A
#21 b
#31K

这里有一个处理不同情况的函数

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    
不喜欢1%
解组
}else if(ops=='和'){
df%>%
分组依据(id)%>%
筛选器(!全部(不喜欢%name中的%1))%>%
解组
}
}
myfun(数据,不喜欢1)
#一个tibble:5x2
#身份证名称
#  
#11A
#21 b
#31K
#4楼
#54U
myfun(数据,不喜欢2,'和')
#一个tibble:8x2
#身份证名称
#  
#11A
#21 b
#31K
#4.2 b
#5.2 e
#6.2克
#7.4楼
#84U
myfun(数据,不喜欢2“或”)
#一个tibble:3x2
#身份证名称
#  
#11A
#21 b
#31K

你好,非常感谢。它适用于第一个案例(您创建的案例)和最后一个具有
data[!(data$id%在%unique中(data[data$name='e'| data$name='f','id']),]
,但如何管理第二个呢?使用
data[!(data$id%in%unique(data[data$name='e',data$name='f','id']),]
并不能提供一个好的答案,也许我做错了什么。它不是一条直线,而是相交(data[which(data$name='e'),'id'],data[which(data$name='f'),'id']))将为您提供一个id列表,然后您可以使用%in%运算符删除您正在说的
data[!(data$id%in%unique(intersect(data[which(data$name='e')、'id']、data[which(data$name='f')、'id']),]),]
?非常多,但您在一行中打包了太多内容,难以阅读。您好,谢谢。它适用于第一个案例(您创建的案例)和最后一个具有
data[!(data$id%在%unique中(data[data$name='e'| data$name='f','id']),]
,但如何管理第二个呢?使用
data[!(data$id%in%unique(data[data$name='e',data$name='f','id']),]
并不能提供一个好的答案,也许我做错了什么。它不是一条直线,而是相交(data[which(data$name='e'),'id'],data[which(data$name='f'),'id']))将为您提供一个id列表,然后您可以使用%in%运算符删除您正在说的
data[!(data$id%in%unique(intersect(data[which(data$name='e'),'id'],data[which(data$name='f'),'id']),]),]
,差不多,但是您在一行中打包了太多内容,使其难以阅读。请参见查看如何仅
myfun%groupby(id)%%>%filter(!fun(不喜欢%in%name))%%>%ungroup}
?然后你可以做
myfun(data,dislike2,any)
myfun(data,dislike2,all)
那就
myfun%groupby(id)%%>%filter(!fun(dislike%in%name))%%>%ungroup}怎么样?然后你可以做
myfun(data,dislike2,any)
myfun(data,dislike2,all)
data[,if(!any(name%in%to_del)).SD,by=“id”]
会更快
data[,if(!any(name%in%to_del)).SD,by=“id”
会更快
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