2015-05-18 4 views
6

У меня есть данные, что выглядит следующим образом:Вычитание конкретные строки

Participant Round Total 
1  100  5 
1  101  8 
1  102  12 
1  200  42  
2  100  14 
2  101  71 
40  100  32 
40  101  27 
40  200  18 

Я хочу, чтобы получить таблицу с Total последнего Round (200) минус Total первого Round (100);

Например, для участника 1 - это 42 - 5 = 37.

Конечный результат должен выглядеть следующим образом:

Participant Total 
1   37 
2  
40  -14 
+0

Большое спасибо! Я застрял - но теперь я нашел решение (хотя и менее элегантное, чем предлагаемое здесь 2); expEnd = exp [exp $ Number_round == 200,] expBegin = exp [exp $ Number_round == 100,] Total_new = expEnd $ Total - expBegin $ Total – YefR

ответ

1

вы можете попробовать это

library(dplyr) 
group_by(df, Participant) %>% 
    filter(row_number()==1 | row_number()==max(row_number())) %>% 
    mutate(df = diff(Total)) %>% 
    select(Participant, df) %>% 
    unique() 
Source: local data frame [3 x 2] 
Groups: Participant 

    Participant df 
1   1 37 
2   2 57 
3   40 -14 
12

С основания R

aggregate(Total ~ Participant, df[df$Round %in% c(100, 200), ], diff) 
# Participant Total 
# 1   1 37 
# 2   2  
# 3   40 -14 

Или так же в сочетании с subset

aggregate(Total ~ Participant, df, subset = Round %in% c(100, 200), diff) 

Или с data.table

library(data.table) ; 
setDT(df)[Round %in% c(100, 200), diff(Total), by = Participant] 
# Participant V1 
# 1:   1 37 
# 2:   40 -14 

или с помощью двоичного присоединиться

setkey(setDT(df), Round) 
df[.(c(100, 200)), diff(Total), by = Participant] 
# Participant V1 
# 1:   1 37 
# 2:   40 -14 

Или с dplyr

library(dplyr) 
df %>% 
    group_by(Participant) %>% 
    filter(Round %in% c(100, 200)) %>% 
    summarise(Total = diff(Total)) 
# Source: local data table [2 x 2] 
# 
# Participant Total 
# 1   1 37 
# 2   40 -14 
+1

Я пытаюсь понять ваш код (который, кстати, умный): что делает 'Total [c (1L, .N)]' do? Я предполагаю, что я могу просто ссылаться на столбец каждой SD напрямую и не нужно вводить '.SD [, Total]', но что делает 'c (1L, .N)' do? – grrgrrbla

+0

Он просто выбирает первое и последнее значение, так как они всегда '100' и' 200' в приведенном примере. –

+0

это я понял из тестирования, я прав, что 1L просто выбирает первый элемент (используя 1L вместо 1, потому что целые числа требуют меньше памяти, чем double/float), а .N дает количество элементов в списке, так что я могу выбрать последний? так что это будет то же самое, что сказать «nrow (dt)»? – grrgrrbla

2

попробовать это:

df <- read.table(header = TRUE, text = " 
Participant Round Total 
       1  100  5 
1  101  8 
1  102  12 
1  200  42  
2  100  14 
2  101  71 
2 200 80 
40  100  32 
40  101  27 
40  200  18") 

library(data.table) 
setDT(df)[ , .(Total = Total[Round == 200] - Total[Round == 100]), by = Participant] 
1

Каждый любит немного sqldf, так что если ваше требование не использовать применять то попробуйте это:

Во-первых некоторые тестовые данные:

df <- read.table(header = TRUE, text = " 
Participant Round Total 
       1  100  5 
1  101  8 
1  102  12 
1  200  42  
2  100  14 
2  101  71 
2 200 80 
40  100  32 
40  101  27 
40  200  18") 

Следующая использование SQL для создания 2 столбцов - один для 100 раундов и один для раунда 200 и вычесть их

rolled <- sqldf(" 
    SELECT tab_a.Participant AS Participant 
     ,tab_b.Total_200 - tab_a.Total_100 AS Difference 
    FROM (
     SELECT Participant 
      ,Total AS Total_100 
     FROM df 
     WHERE Round = 100 
     ) tab_a 
    INNER JOIN (
     SELECT Participant 
      ,Total AS Total_200 
     FROM df 
     WHERE Round = 200 
     ) tab_b ON (tab_a.Participant = tab_b.Participant) 
    ") 
Смежные вопросы