我的数据包括运动员在不同时期完成的活动的时间戳。每个时期最多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'))
我尝试过以下代码,但这并没有返回我预期的输出。
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问题,我了解可以找到列中因子变化的索引,如何安排此代码以获得所需的输出?
谢谢。
答案 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)
请注意,这需要以正确的方式对数据进行排序。