根据条件,提取变量中的行以进行更改

时间:2017-03-15 04:24:45

标签: r

我的数据包括运动员在不同时期完成的活动的时间戳。每个时期最多20分钟。注意到相应的天气条件。

我想说出第一次出现的天气和条件变化。我的问题类似于this question,除了我想要第一次出现以及何时发生变化。

我的数据结构如下:

  df <- data.frame(Time=c("0:00:00","0:01:00","0:02:40","0:12:09",
                        "0:00:00", "0:02:07","0:07:19","0:15:16",
                        "0:00:00", "0:03:00","0:08:40","0:13:29",
                        "0:00:00", "0:02:10","0:08:47","0:17:55"),
                 Athlete = c('Paul', 'Paul', 'Paul', 'Paul',
                             'Paul', 'Paul', 'Paul','Paul',
                            'Joe', 'Joe', 'Joe', 'Joe',
                            'Joe', 'Joe', 'Joe', 'Joe'),
                 Period = c('P1', 'P1', 'P1', 'P1',
                            'P2', 'P2', 'P2', 'P2',
                            'P1', 'P1', 'P1', 'P1',
                            'P2', 'P2', 'P2', 'P2'),
                 Weather = c('Sunny', 'Sunny', 'Sunny', 'Cloudy',
                            'Rain', 'Cloudy', 'Rain', 'Rain',
                            'Rain', 'Sunny', 'Rain', 'Rain',
                            'Sunny', 'Sunny', 'Cloudy', 'Cloudy'))
  1. 根据每个运动员和时期,我如何召唤第一次出现并改变天气?
  2. 我如何在minutes.seconds中有时间?例如:2.40
  3. 我尝试过以下代码,但这并没有返回我预期的输出。

    Test <- df[match(unique(df$Weather), df$Weather),]
    

    我的预期输出是:

    Output <- data.frame(Time = c(0.0, 12.09, 
                                  0.0, 2.07, 7.19, 
                                  0.0, 3.00, 8.40, 
                                  0.0, 8.47), 
                         Athlete = c('Paul', 'Paul', 
                                     'Paul', 'Paul', 'Paul',
                                     'Joe', 'Joe', 'Joe', 
                                     'Joe', 'Joe'), 
                         Period = c('P1', 'P1', 
                                    'P2', 'P2', 'P2',
                                    'P1', 'P1', 'P1', 
                                    'P2', 'P2'), 
                         Weather = c('Sunny', 'Cloudy', 
                                     'Rain', 'Cloudy', 'Rain', 
                                     'Rain', 'Sunny', 'Rain', 
                                     'Sunny', 'Cloudy'))
    

    this问题,我了解可以找到列中因子变化的索引,如何安排此代码以获得所需的输出?

    谢谢。

2 个答案:

答案 0 :(得分:1)

我建议使用来自&#34; data.table&#34;的rleid之类的内容。你可以这样做:

library(data.table)
as.data.table(df)[, ind := sequence(.N), rleid(Athlete, Period, Weather)][ind == 1]
##        Time Athlete Period Weather ind
##  1: 0:00:00    Paul     P1   Sunny   1
##  2: 0:12:09    Paul     P1  Cloudy   1
##  3: 0:00:00    Paul     P2    Rain   1
##  4: 0:02:07    Paul     P2  Cloudy   1
##  5: 0:07:19    Paul     P2    Rain   1
##  6: 0:00:00     Joe     P1    Rain   1
##  7: 0:03:00     Joe     P1   Sunny   1
##  8: 0:08:40     Joe     P1    Rain   1
##  9: 0:00:00     Joe     P2   Sunny   1
## 10: 0:08:47     Joe     P2  Cloudy   1

关于你的问题&#34;我如何有时间在minutes.seconds?例如:2.40 - 这不是真正表达时间的标准方式,是吗? 0.4 * 60 = 24,所以我不建议以这种方式转换它。

如果您希望将这些值作为数值,则可以将它们拆分为单独的列。为此,我推荐我的&#34; splitstackshape&#34;封装

library(splitstackshape)
cSplit(as.data.table(df)[
  , ind := sequence(.N), rleid(Athlete, Period, Weather)][ind == 1][
    , ind := NULL][], "Time", ":")
##     Athlete Period Weather Time_1 Time_2 Time_3
##  1:    Paul     P1   Sunny      0      0      0
##  2:    Paul     P1  Cloudy      0     12      9
##  3:    Paul     P2    Rain      0      0      0
##  4:    Paul     P2  Cloudy      0      2      7
##  5:    Paul     P2    Rain      0      7     19
##  6:     Joe     P1    Rain      0      0      0
##  7:     Joe     P1   Sunny      0      3      0
##  8:     Joe     P1    Rain      0      8     40
##  9:     Joe     P2   Sunny      0      0      0
## 10:     Joe     P2  Cloudy      0      8     47

&#34; Time_1&#34;会是几个小时,&#34; Time_2&#34;将是分钟,&#34; Time_3&#34;会是秒。

如果你真的想要&#34; Time&#34;如你所描述的那样,你可以用以下的方式做到:

df$Time <- as.numeric(sub(":", ".", gsub("^[^:]*:", "", df$Time)))

然后,继续使用&#34; data.table&#34;前面描述的方法。

&#34; tidyverse&#34;方法(仍然使用来自&#34; data.table&#34;)的rleid可能看起来像这样:

library(tidyverse)
library(data.table)

df %>%
  mutate(ind = rleid(Athlete, Period, Weather)) %>%
  group_by(ind) %>%
  slice(1) %>%
  ungroup() %>%
  select(-ind) %>%
  mutate(Time = as.numeric(sub(":", ".", gsub("^[^:]*:", "", Time))))
# # A tibble: 10 × 4
#     Time Athlete Period Weather
#    <dbl>  <fctr> <fctr>  <fctr>
# 1   0.00    Paul     P1   Sunny
# 2  12.09    Paul     P1  Cloudy
# 3   0.00    Paul     P2    Rain
# 4   2.07    Paul     P2  Cloudy
# 5   7.19    Paul     P2    Rain
# 6   0.00     Joe     P1    Rain
# 7   3.00     Joe     P1   Sunny
# 8   8.40     Joe     P1    Rain
# 9   0.00     Joe     P2   Sunny
# 10  8.47     Joe     P2  Cloudy

答案 1 :(得分:1)

不是超级优雅的版本:

df %>% filter(c(1,diff(as.numeric(Athlete)))!=0 |
              c(1,diff(as.numeric(Weather)))!=0 |
              c(1,diff(as.numeric(Period)))!=0) 

请注意,这需要以正确的方式对数据进行排序。