【问题标题】:Subsetting data based on a value within ids in r基于 r 中 ids 内的值对数据进行子集化
【发布时间】:2020-04-27 14:17:50
【问题描述】:

我正在尝试根据两个标准对数据集进行子集化。这是我的数据快照:

ids <-  c(1,1,1,1,1,1, 2,2,2,2,2,2, 3,3,3,3,3,3)
seq <-  c(1,2,3,4,5,6, 1,2,3,4,5,6, 1,2,3,4,5,6)
type <- c(1,1,5,1,1,1, 1,1,1,8,1,1, 1,1,1,1,1,1)
    data <- data.frame(ids, seq, type)

   ids seq type
1    1   1    1
2    1   2    1
3    1   3    5
4    1   4    1
5    1   5    1
6    1   6    1
7    2   1    1
8    2   2    1
9    2   3    1
10   2   4    8
11   2   5    1
12   2   6    1
13   3   1    1
14   3   2    1
15   3   3    1
16   3   4    1
17   3   5    1
18   3   6    1

ids 是学生 ID,seq 是学生回答的问题(项目)的顺序。 type 指问题的类型。 1 是简单的,58 是复杂的项目。我想做的是生成第一个变量(complex)来判断学生是否有复杂的项目(type=5|8)。然后我想得到:

   > data
   ids seq type complex
1    1   1    1       1
2    1   2    1       1
3    1   3    5       1
4    1   4    1       1
5    1   5    1       1
6    1   6    1       1
7    2   1    1       1
8    2   2    1       1
9    2   3    1       1
10   2   4    8       1
11   2   5    1       1
12   2   6    1       1
13   3   1    1       0
14   3   2    1       0
15   3   3    1       0
16   3   4    1       0
17   3   5    1       0
18   3   6    1       0

第二步是在学生内部拆分数据。 (a) 对于有非复杂项目的学生(complex=0),我想将数据集从半点拆分并得到以下结果:

>simple.split.1
    ids seq type   complex
13   3   1    1       0
14   3   2    1       0
15   3   3    1       0

>simple.split.2
    ids seq type   complex
16   3   4    1       0
17   3   5    1       0
18   3   6    1       0

(b)对于有复杂项目的学生(complex=1),我想将复杂项目设置为切割点并从那里分割数据。所以数据应该是这样的(不包括复杂项):

   >complex.split.1
    ids seq type   complex
1    1   1    1       1
2    1   2    1       1
7    2   1    1       1
8    2   2    1       1
9    2   3    1       1

    >complex.split.2
    ids seq type   complex
4    1   4    1       1
5    1   5    1       1
6    1   6    1       1
11   2   5    1       1
12   2   6    1       1

有什么想法吗? 谢谢

【问题讨论】:

    标签: r split conditional-statements subset


    【解决方案1】:

    这是一种使用data.tablezoo 包和split 函数的方法:

    library(data.table)
    library(zoo)
    
    setDT(data)[, complex := ifelse(type == 5 | type == 8, 1, NA_integer_), by = ids][, complex := na.locf(na.locf(complex, na.rm=FALSE), na.rm=FALSE, fromLast=TRUE), by = ids][, complex := ifelse(is.na(complex), 0, complex)] ## set data to data.table & add a flag 1 where type is 5 or 8 ## carry forward and backward of complex flag ## replace na values in complex column with 0
    
    data <- data[!(type == 5 | type == 8), ] ## removing rows where type equals 5 or 8
    
    complex <- split(data, data$complex) ## split data based on complex flag
    
    complex_0 <- as.data.frame(complex$`0`) ## saving as data frame based on complex flag
    complex_1 <- as.data.frame(complex$`1`)
    
    split(complex_0, cut(complex_0$seq, 2)) ## split into equal parts
    split(complex_1, cut(complex_1$seq, 2))
    
    
    #$`(0.995,3.5]`
    #   ids seq type complex
    #1   3   1    1       0
    #2   3   2    1       0
    #3   3   3    1       0
    
    #$`(3.5,6]`
    #   ids seq type complex
    #4   3   4    1       0
    #5   3   5    1       0
    #6   3   6    1       0
    
    
    
        #$`(0.995,3.5]`
    #   ids seq type complex
    #1   1   1    1       1
    #2   1   2    1       1
    #6   2   1    1       1
    #7   2   2    1       1
    #8   2   3    1       1
    
    #$`(3.5,6]`
    #    ids seq type complex
    #3    1   4    1       1
    #4    1   5    1       1
    #5    1   6    1       1
    #9    2   5    1       1
    #10   2   6    1       1
    

    【讨论】:

    • 感谢您的解决方案@sm925,复杂数据的类型=8 行,但可以轻松删除。感谢您的宝贵时间!
    • @amisos55 要求没有删除这些行。我会尽快更新我的答案。
    【解决方案2】:

    如果您更喜欢使用tidyverse,这里有一个方法:

    ids <-  c(1,1,1,1,1,1, 2,2,2,2,2,2, 3,3,3,3,3,3)
    seq <-  c(1,2,3,4,5,6, 1,2,3,4,5,6, 1,2,3,4,5,6)
    type <- c(1,1,5,1,1,1, 1,1,1,8,1,1, 1,1,1,1,1,1)
    data <- data.frame(ids, seq, type)
    
    step1.data <- data %>%
      group_by(ids) %>%
      mutate(complex = ifelse(any(type %in% c(5,8)), 1, 0)) %>%
      ungroup()
    
    simple.split.1 <- step1.data %>%
      filter(complex == 0) %>%
      group_by(ids) %>%
      filter(seq <= mean(seq)) %>% #if you happen to have more than 6 questions in seq, this gives the midpoint
      ungroup()
    
    simple.split.2 <- step1.data %>%
      filter(complex == 0) %>%
      group_by(ids) %>%
      filter(seq > mean(seq)) %>%
      ungroup()
    
    complex.split.1 <- step1.data %>%
      filter(complex == 1) %>%
      arrange(ids, seq) %>%
      group_by(ids) %>%
      filter(seq < min(seq[type %in% c(5,8)])) %>%
      ungroup()
    
    complex.split.2 <- step1.data %>%
      filter(complex == 1) %>%
      arrange(ids, seq) %>%
      group_by(ids) %>%
      filter(seq > min(seq[type %in% c(5,8)])) %>%
      ungroup()
    

    【讨论】:

    • 感谢您的时间和解决方案@Kyle。这真的很好用。
    • 乐于助人!
    猜你喜欢
    • 2016-12-16
    • 2017-03-24
    • 1970-01-01
    • 2019-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多