2017-01-13 1 views
1

Используя следующие данные:
арифметической операции между группой два

set.seed(1234) 

df1 <- structure(
    list(wavelength = c(400, 400, 400, 400, 400, 400, 400, 400, 500, 500, 500, 500, 500, 500, 500, 500), 
     depth = c(0, 30, 40, 60, 79, 89, 101, 110, 0, 30, 40, 60, 79, 89, 101, 110), 
     value = sample(16)), 
    class = "data.frame", row.names = c(NA, -16L), .Names = c("wavelength", "depth", "value")) 

df1 
#> wavelength depth value 
#> 1   400  0  2 
#> 2   400 30 10 
#> 3   400 40  9 
#> 4   400 60 14 
#> 5   400 79 11 
#> 6   400 89  8 
#> 7   400 101  1 
#> 8   400 110  3 
#> 9   500  0  6 
#> 10  500 30  4 
#> 11  500 40  5 
#> 12  500 60 13 
#> 13  500 79 16 
#> 14  500 89 12 
#> 15  500 101 15 
#> 16  500 110  7 

Как это возможно, чтобы сгруппировать данные по wavelength, а затем рассчитать res таким образом, что она представляет собой арифметическую операцию между парами value. В этом примере res представляет собой просто сумму квадратов между парами. res[1] - это просто 2^2 + 10^2, а res [2] - 10^2 + 9^2 и т. Д.

df2 <- structure(
    list(wavelength = c(400, 400, 400, 400, 400, 400, 400, 500, 500, 500, 500, 500, 500, 500), 
     depth = rep(c("0-30", "30-40", "40-60", "60-79", "79-89", "89-101", "101-110"), 2), 
     res = c(104, 181, 277, 317, 185, 65, 45, 52, 41, 194, 425, 400, 369, 274)), 
    class = "data.frame", row.names = c(NA, -14L), .Names = c("wavelength", "depth", "res")) 

df2 
#> wavelength depth res 
#> 1   400 0-30 104 
#> 2   400 30-40 181 
#> 3   400 40-60 277 
#> 4   400 60-79 317 
#> 5   400 79-89 185 
#> 6   400 89-101 65 
#> 7   400 101-110 45 
#> 8   500 0-30 52 
#> 9   500 30-40 41 
#> 10  500 40-60 194 
#> 11  500 60-79 425 
#> 12  500 79-89 400 
#> 13  500 89-101 369 
#> 14  500 101-110 274 

В идеале, ответ будет использовать синтаксис dplyr.

Update

На основании полученных ответов я пришел с этим решением.


f1 <- function(x, y) { 
    return(x^2 + y^2) 
} 

df1 %>% 
    group_by(wavelength) %>% 
    mutate(depth = paste(depth, lead(depth), sep = "-")) %>% 
    mutate(res = f1(value, c(lead(value)))) %>% 
    na.omit() 


#> Source: local data frame [14 x 4] 
#> Groups: wavelength [2] 
#> 
#> wavelength depth value res 
#>   <dbl> <chr> <int> <dbl> 
#> 1   400 0-30  2 104 
#> 2   400 30-40 10 181 
#> 3   400 40-60  9 277 
#> 4   400 60-79 14 317 
#> 5   400 79-89 11 185 
#> 6   400 89-101  8 65 
#> 7   400 101-110  1 10 
#> 8   500 0-30  6 52 
#> 9   500 30-40  4 41 
#> 10  500 40-60  5 194 
#> 11  500 60-79 13 425 
#> 12  500 79-89 16 400 
#> 13  500 89-101 12 369 
#> 14  500 101-110 15 274 
+0

Вы попробовали лаг()? – Haboryme

ответ

2

После того, как группировка по 'длине волны', создать столбец 'глубина' с помощью paste Инг на 'глубину' с 'свинцом' из «глубин 'и' значение 'по разности смежных элементов (diff), затем удалите элементы NA с помощью na.omit

library(dplyr) 
df1 %>% 
    group_by(wavelength) %>% 
    mutate(depth = paste(depth, lead(depth), sep="-"), 
      value = c(diff(value), NA)) %>% na.omit() 
# wavelength depth value 
#  <dbl> <chr> <int> 
#1   400 0-30  8 
#2   400 30-40 -1 
#3   400 40-60  5 
#4   400 60-79 -3 
#5   400 79-89 -3 
#6   400 89-101 -7 
#7   400 101-110  2 
#8   500 0-30 -2 
#9   500 30-40  1 
#10  500 40-60  8 
#11  500 60-79  3 
#12  500 79-89 -4 
#13  500 89-101  3 
#14  500 101-110 -8 
+1

Работа как ожидание. Принят ответ. –

+0

@PhilippeMassicotte Пожалуйста, обновите свой вопрос, поскольку из комментария не ясно – akrun

+2

@PhilippeMassicotte Напишите функцию из двух варов: f = function (a, b) a^2 + b^2', затем используйте ее в своем мутате, например, 'mutate (res = f (head (value, -1), tail (value, -1))) или аналогичный. – Frank