R基于层次数据中的儿子删除父亲行

时间:2018-06-14 12:48:29

标签: 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
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。
这可能也是“我不喜欢ef一起”的任务:

    > 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

或者,“如果你有ef”,我就不要你了:

> 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

正如您已经注意到的那样,为了更清楚,我已经“评论”了必须删除的行。

我已经搜索了,但是我发现很多问题只基于data[which(data$name=='e'),]这样的一列,但这只会在儿子的级别上删除,而不是相对父亲的所有行。

我也考虑过将数据放在宽格式中,将id的所有名称粘贴到一个唯一的单元格中,然后获取是否有e,例如像grepl()这样的函数,但我认为这可能是大型数据集的问题(这些数据就是一个例子)。

你对如何管理这个有任何想法吗?
提前致谢

3 个答案:

答案 0 :(得分:2)

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

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 :(得分:1)

data[!(data$id %in% unique(data[data$name == 'e', 'id'])),]

unique(data [data $ name =='e','id'])将获得名称字段中包含'e'的唯一ID。然后,您可以使用%in%运算符查找具有这些ID的所有行。的!是一个否定运算符。

答案 2 :(得分:0)

我有一个data.table解决方案

public T ReadRecord<T>(int recordId) where T : MoxRecord {}