基于匹配值减去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")