попарное вычитание в кадре данных с группами разной длины

У меня есть фрейм данных в 18528 строк и 3 столбца, как показано ниже:

Sample  Target  Value
100      A       21.5
100      A       20.5
100      B       19.5
100      B       19.75
100      B       18.15
100      B       21.95
200      A       21.1
200      A       21.6
200      B       23.5
200      B       20.75
100      C       21.25
100      C       22.0
100      C       18.33
100      C       21.84

Мне нужно рассчитать разницу между значениями в каждой группе:

Sample  Target  Value   dif
100      A       21.5   1
100      A       20.5   1
100      B       19.5   0.25
100      B       19.75  1.6
100      B       18.15  3.8
100      B       21.95  2.45
200      A       21.1   0.5
200      A       21.6   0.5
200      B       23.5   2.75
200      B       20.75  2.75
100      C       21.25  0.75
100      C       22.0   3.67
100      C       18.33  3.51
100      C       21.84  0.59

Затем, если разница больше 2, сделайте это значение «NA», например:

Sample  Target  Value   dif
100      A       21.5   1
100      A       20.5   1
100      B       19.5   0.25
100      B       19.75  1.6
100      B       18.15  3.8
100      B       NA     2.45
200      A       21.1   0.5
200      A       21.6   0.5
200      B       NA     2.75
200      B       NA     2.75
100      C       21.25  0.75
100      C       22.0   3.67
100      C       NA     3.51
100      C       21.84  0.59

Я использовал combn для вычисления разницы, но получил ошибку, думаю, причина может быть в разной длине в группах (2 и 4). заранее спасибо


person Lili    schedule 09.04.2015    source источник
comment
Группа - это пара (образец, цель), я полагаю? На самом деле на выходе, который вы представляете, вы выводите значение строки 3 в значение строки 2, чтобы получить разницу в строке 2...   -  person Colonel Beauvel    schedule 09.04.2015
comment
точно, и спасибо за редактирование :)   -  person Lili    schedule 09.04.2015
comment
да, но мое замечание заключалось в том, что существует большая разница между тем, что вы сказали о группе, и тем, что вы представили в качестве вывода (там нет группировки, поскольку вы берете разницу последовательных значений). Поэтому мне интересно, что вы, наконец, хотите в результате ...   -  person Colonel Beauvel    schedule 09.04.2015
comment
что я имею в виду; есть 5 групп (A-100, B-100, A-200, B-200, C-100), и я хочу рассчитать разницу между значениями в каждой группе.   -  person Lili    schedule 09.04.2015
comment
На самом деле вам нужно рассчитать только разницу между вашим значением и максимальным и минимальным значением внутри группы.   -  person Colonel Beauvel    schedule 09.04.2015
comment
Но хтать явно не то, что вы написали во второй таблице...   -  person Colonel Beauvel    schedule 09.04.2015
comment
Какой код вы использовали для перехода от первого дисплея ко второму?   -  person Marichyasana    schedule 09.04.2015


Ответы (1)


Вы можете получить желаемый результат, используя пакет dplyr. Если он у вас не установлен, сначала запустите команду install.packages("dplyr") или установите его вручную.

Тогда что имеем:

require("dplyr")

mydf <- read.table(text = "
Sample  Target  Value
100      A       21.5
100      A       20.5
100      B       19.5
100      B       19.75
100      B       18.15
100      B       21.95
200      A       21.1
200      A       21.6
200      B       23.5
200      B       20.75
100      C       21.25
100      C       22.0
100      C       18.33
100      C       21.84", header = T)

mydf1 <- mydf %>% group_by(Sample, Target) %>% 
  mutate(ValueShifted = c(Value[-1], Value[1]) ) %>%
  mutate(dif = abs(Value - ValueShifted) ) %>%
  mutate(NewValue = c(1, NA)[(as.numeric(dif > 2)+1)] * Value )

> mydf1
Source: local data frame [14 x 6]
Groups: Sample, Target

   Sample Target Value ValueShifted  dif NewValue
1     100      A 21.50        20.50 1.00    21.50
2     100      A 20.50        21.50 1.00    20.50
3     100      B 19.50        19.75 0.25    19.50
4     100      B 19.75        18.15 1.60    19.75
5     100      B 18.15        21.95 3.80       NA
6     100      B 21.95        19.50 2.45       NA
7     200      A 21.10        21.60 0.50    21.10
8     200      A 21.60        21.10 0.50    21.60
9     200      B 23.50        20.75 2.75       NA
10    200      B 20.75        23.50 2.75       NA
11    100      C 21.25        22.00 0.75    21.25
12    100      C 22.00        18.33 3.67       NA
13    100      C 18.33        21.84 3.51       NA
14    100      C 21.84        21.25 0.59    21.84
person inscaven    schedule 09.04.2015
comment
Спасибо, это как-то работает, но в последней группе 18.33 должно быть NA, если это сделать остальные отличия в этой группе будут меньше 2 и во второй группе будет то же самое (21.95). - person Lili; 09.04.2015
comment
Хорошо, я не совсем понял правило вычисления dif. Как это будет выглядеть для x = c(1.1, 1.5, 2.5, 3) ? Я предполагал просто разницу x[i] - x[i+1] для i-й строки с зацикливанием до первого значения в конце. Но, возможно, я ошибаюсь в вычислении dif, так что поправьте меня. Еще один вопрос (вопросы): вам нужно удалить минимальный набор значений, чтобы все difs ‹ 2 ? Это то же состояние, что и (max(Value) - min(Value)) < 2 внутри группы? А что, если значения в группе 15 15.5 19.5 20? Итак, не могли бы вы уточнить, что вам нужно делать с данными и каковы правила. - person inscaven; 09.04.2015
comment
Спасибо за внимание, можно сказать, будет удалено значение, которое имеет разницу более 2, в 15 15,5 19,5 20; 15 и 15.5 надо убрать, т.к. 19.5-15.5=4›2 и 20-15=5›2 после удаления этих значений получим 19.5 и 20, то есть разница меньше 2. Надеюсь понятно объяснил. - person Lili; 10.04.2015