r语言 - 按二分组之间的算术运算



使用以下数据:

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对数据进行分组,然后以表示value对之间的算术运算的方式计算res。在此示例中,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语法。

更新

根据收到的答案,我想出了这个解决方案。


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

按"波长"分组后,通过将"深度"与"深度"的"前导"和相邻元素的差值(diff)的"前导"paste来创建"深度"列,然后删除带有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

最新更新