【问题标题】:R: Rows Fulfilling a Vector of Different CriteriaR:满足不同标准向量的行
【发布时间】:2018-06-18 22:41:48
【问题描述】:

假设我有一个数据框event_data,看起来像这样:

  ID event_one event_two
1  A         1         8
2  B         3         5
3  C         9        13
4  D         9        13
5  E        10        10
6  F        13        15
7  G        13        17
8  H        14        17
9  I        15        19

event 列是从某个初始时间 0 到事件发生所经过的时间量。所以对于对象Cevent_one 发生在时间 9,event_two 发生在时间 13。

我想要的是取times的向量:

> times = 0:20
> times
 [1]  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

然后浏览这两列,找出每次发生的次数。输出应如下所示:

time    event_ones      event_twos
0       0               0
1       1               0
2       0               0
3       1               0
4       0               0
5       0               1
6       0               0
7       0               0
8       0               1
9       2               0
10      1               1
11      0               0
12      0               0
13      2               2
14      1               0
15      1               1
16      0               0
17      0               2
18      0               0
19      0               1
20      0               0

我意识到我可以通过遍历times 中的每个元素并迭代地构建表格来解决这个问题,但是你不应该在 R 中这样做,我怀疑有一种更清洁的方法来做到这一点。如果可能的话,它也应该推广到任意多的列(我给出的例子是简化的;我的真实数据有更多这样的事件,我必须找到时间计数)。

【问题讨论】:

    标签: r for-loop dataframe vector


    【解决方案1】:

    不需要任何软件包。转换为因子和表格:

    data.frame(
        time=0:20,
        lapply(
            dat[c("event_one","event_two")],
            function(x) c(table(factor(x, levels=0:20)))
        )
    )
    

    不太清楚,你可以使用tabulate

    data.frame(time=0:20, lapply(dat[c("event_one","event_two")]+1, tabulate, nbins=21))
    

    【讨论】:

      【解决方案2】:

      这需要dplyr 包。首先,我创建一个虚拟数据框。

      # Dummy data frame
      df <- data.frame(event_one = sample(1:20, 10, replace = TRUE),
                       event_two = sample(1:20, 10, replace = TRUE))
      

      接下来,我定义了一个函数,该函数使用table 对每个事件进行计数,并将输出重新打包为一个数据框。

      # Tabulating function
      dain_table <- function(foo){
        data.frame(table(foo)) %>% 
          rename(times = foo)
      }          
      

      最后,我将函数应用于我的虚拟数据框中的每一列,并将其加入所有可能的times

      # Package it all together
      Reduce(function(x, y)left_join(x, y, by = 'times'), lapply(df, dain_table)) %>% 
        mutate(times = as.numeric(times)) %>% 
        right_join(data.frame(times = 1:20))
      
      #    times Freq.x Freq.y
      # 1      1     NA     NA
      # 2      2     NA     NA
      # 3      3     NA     NA
      # 4      4      1     NA
      # 5      5     NA     NA
      # 6      6     NA     NA
      # 7      7     NA     NA
      # 8      8      1      1
      # 9      9      1     NA
      # 10    10      1      1
      # 11    11     NA     NA
      # 12    12      1     NA
      # 13    13      1     NA
      # 14    14     NA     NA
      # 15    15     NA     NA
      # 16    16     NA     NA
      # 17    17     NA     NA
      # 18    18      2      2
      # 19    19      2      1
      # 20    20     NA     NA
      

      【讨论】:

        【解决方案3】:
        df2   <- rbind(data.frame(event="one",time=df$event_one), 
                       data.frame(event="two",time=df$event_two))
        times <- data.frame(time=1:20)
        
        
        library(dplyr)    
        library(tidyr)
        
        df <- times %>% 
          left_join(df2, by=c("time" = "time")) %>% 
          group_by(time,event) %>% 
          summarize(count=n()) %>% 
          spread(event, count) %>% 
          replace_na(list(one = 0, two = 0))
        
        print(df[,1:3], row.names=F)
        
        # A tibble: 20 x 3
        # Groups:   time [20]
            time   one   two
           <int> <dbl> <dbl>
         1     1    1.    0.
         2     2    0.    0.
         3     3    1.    0.
         4     4    0.    0.
         5     5    0.    1.
         6     6    0.    0.
         7     7    0.    0.
         8     8    0.    1.
         9     9    2.    0.
        10    10    1.    1.
        11    11    0.    0.
        12    12    0.    0.
        13    13    2.    2.
        14    14    1.    0.
        15    15    1.    1.
        16    16    0.    0.
        17    17    0.    2.
        18    18    0.    0.
        19    19    0.    1.
        20    20    0.    0.
        

        您会注意到,在print() 中,我以 1:3 的比例对列进行了索引。那只是因为它还创建了第 4 个“NA”类别列,表示没有事件的时间。你可以丢弃它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-11-20
          • 2012-04-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-01
          相关资源
          最近更新 更多