基于匹配值减去R中的行
我正在尝试从数据集中的两行中减去另一行:基于匹配值减去R中的行,r,R,我正在尝试从数据集中的两行中减去另一行: Name Period Time Distance Load Tim A 01:06:20 6000 680 Max A 01:06:20 5000 600 Leo A 01:06:20 5500 640 Noa A 01:06:20 6500 700 Tim B 00:04:10 500 80 M
Name Period Time Distance Load
Tim A 01:06:20 6000 680
Max A 01:06:20 5000 600
Leo A 01:06:20 5500 640
Noa A 01:06:20 6500 700
Tim B 00:04:10 500 80
Max B 00:04:10 500 50
Leo B 00:04:10 400 40
我想从周期A中减去周期B的时间、距离和负载值,以匹配名称。
例如,从第1行Tim周期A中减去第5行Tim周期B
新值应写入新表,如下所示:
Name Period Time Distance Load
Tim C 01:02:10 5500 600
Max C 01:02:10 4500 550
Leo C 01:02:10 5100 600
Noa C 01:06:20 6500 700
真正的数据集包含更多的行。我试着和dplyr一起玩,但是没有得到我想要的结果
提前感谢您可以对这两个句点进行筛选,然后将它们连接在一起,从而简化列的减法
library(dplyr)
inner_join(filter(df, Period=="A"), filter(df, Period=="B"), by="Name") %>%
mutate(Period="C",
Time=Time.x-Time.y,
Distance=Distance.x-Distance.y,
Load=Load.x-Load.y) %>%
select(Name, Period, Time, Distance, Load)
这与@Edward的想法基本相同。您可以使用dplyr和tidyr: df%>% pivot\u widernames\u from=周期,值\u from=cTime,距离,负载%>% 变异周期=C, 时间=聚结时间A-时间B,时间A, 距离=聚结距离_A-距离_B,距离_A, 荷载=聚结荷载A-荷载B,荷载A %>% 选择匹配项\\uw 返回 一个tibble:4x5 名称周期时间距离负载 1 Tim C 01:02:10 5500 600 2最大值C 01:02:10 4500 550 3利奥C 01:02:105100 600 4 Noa C 01:06:20 6500 700 资料
df这里有一种不同的方法,通过名称分组来获得差异
library(dplyr)
library(chron)
df <- structure(list(Name = structure(c(4L, 2L, 1L, 3L, 4L, 2L, 1L), .Label = c("Leo", "Max", "Noa", "Tim"), class = "factor"),
Period = structure(c(1L,1L, 1L, 1L, 2L, 2L, 2L), .Label = c("A", "B"), class = "factor"),
Time = structure(c(2L, 2L, 2L, 2L, 1L, 1L, 1L), .Label = c("0:04:10", "1:06:20"), class = "factor"),
Distance = c(6000L, 5000L, 5500L, 6500L, 500L, 500L, 400L),
Load = c(680L, 600L, 640L, 700L, 80L, 50L, 40L)), class = "data.frame", row.names = c(NA, -7L))
df %>%
mutate(Time = times(Time)) %>%
group_by(Name) %>%
mutate(Time = lag(Time) - Time,
Distance = lag(Distance) - Distance,
Load = lag(Load) - Load,
Period = LETTERS[which(LETTERS == Period) + 1]) %>%
filter(!is.na(Time))
您也可以使用data.table
dt <- data.table(Name = c('Tim', 'Max', 'Leo', 'Noa', 'Tim', 'Max', 'Leo'),
Period = c('A', 'A', 'A', 'A', 'B', 'B', 'B'),
Time = c('01:06:20', '01:06:20' , '01:06:20' , '01:06:20' , '00:04:10' , '00:04:10' , '00:04:10' ),
Distance = c(6000, 5000, 5500, 6500, 500, 500, 400 ),
Load = c(680, 600, 640, 700, 80, 50, 40))
然后使用dcast.data.table:
dtCast <- dcast.data.table(dt, Name ~ Period, value.var = c('Time', 'Distance', 'Load'))
有这么多的答案已经,这只是一个有趣的在这个阶段。我认为这种方式很好,因为它使用了最广泛的:
你在第二阶段错过了诺亚。那是故意的吗?是的,那是故意的。我应该澄清一下。句点B是句点A的一部分。但不是每个玩家的名字都有句点B。你是如何写数据的,以便时间在TIBLE中有等级的?我尝试在字符串上使用lubridate::hms,例如01:06:20,但TIBLE看到了这一点,因为我刚刚使用read_table2导入了Tizian的数据,请参见编辑的答案。这门课是自动分配的。太棒了,谢谢!这是我丢失的用于重新创建dput未提供的数据的函数。在许多情况下,此函数工作正常。但有时你必须进一步处理数据才能获得原始数据输入。我明白了,谢谢你@Martin,无论如何,这会让我的生活轻松很多。至于时间问题,我试着使用@Chris在回答中使用的chron包中的times函数,tibble现在将其视为“而不是”您的示例中的“时间”。。。R中的时间和日期对象对我来说仍然很混乱。
dt[, Time := as.POSIXct(Time, format = "%H:%M:%S")]
sapply(dt, class)
dtCast <- dcast.data.table(dt, Name ~ Period, value.var = c('Time', 'Distance', 'Load'))
dtFinal <- dtCast[,list(Period = 'C',
Time = Time_A - Time_B,
Distance = Distance_A - Distance_B,
Load = Load_A - Load_B),
by = 'Name']
library(hms)
dtFinal[, Time := as_hms(Time)]
library(dplyr)
library(tidyr)
library(purrr)
diff <- function(data) {
if(apply(data[2, -1], 1, function(x) all(is.na(x)))) {
data[1, -1]
} else {
data[1, -1] - data[2, -1]
}
}
df %>% group_by(Name) %>% nest() %>%
mutate(diff = map(data, diff)) %>% unnest_wider(diff) %>%
mutate(Period = "C") %>% select(Period, Time, Distance, Load)
# A tibble: 4 x 5
Name Period Time Distance Load
<chr> <chr> <time> <dbl> <dbl>
1 Tim C 01:02:10 5500 600
2 Max C 01:02:10 4500 550
3 Leo C 01:02:10 5100 600
4 Noa C 01:06:20 6500 700
library(readr)
# courtesy of @MartinGal
df <- read_table2("Name Period Time Distance Load
Tim A 01:06:20 6000 680
Max A 01:06:20 5000 600
Leo A 01:06:20 5500 640
Noa A 01:06:20 6500 700
Tim B 00:04:10 500 80
Max B 00:04:10 500 50
Leo B 00:04:10 400 40")