首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将迭代/非聚集函数应用于R中的多个数据子集

将迭代/非聚集函数应用于R中的多个数据子集
EN

Stack Overflow用户
提问于 2019-07-07 08:23:02
回答 1查看 70关注 0票数 0

我正在尝试运行一个需要在数据集的子集内建立索引的函数,但我遇到了如何设置该函数的问题。具体地说,我正在尝试计算给定年份中沿特定横断面的距离,因此对于每个子集,我需要1)识别横断面中的端点,以及2)计算沿线从子集内所有其他位置的端点到该端点的欧几里德距离。

如果我将整个数据集视为单个横断面,则该函数似乎可以工作:

代码语言:javascript
运行
复制
df <- data.frame(
  Transect = c(rep(1,4),rep(2,4)),
  YYYY = c(2015,2015,2016,2016,2015,2015,2016,2016),
  X = seq(2,16, by = 2),
  Y = c(1,2,3,5,6,13,22,31))

df$dist <- NA

f <- function(X, Y) {
  xs_start <- match(min(X), X)  #assumes no transects are perfectly N-S
  for (n in 1:length(X)){
    dist[n] <- (((Y[n]-Y[xs_start])^2)+((X[n]-X[xs_start])^2))^.5
  }
  return(dist)
}
attach(df)
f(X, Y)
detach(df)

然而,在数据的子集上运行它给我带来了麻烦。我可以使用data.tabledplyr成功地设置数据帧的子集,但是在尝试对子集运行函数时,我遇到了不同的问题。我发现的大多数文档都专注于聚合数据子集的方法(有时还会将汇总数字加入整个组)。

使用data.table,我可以获得第一个横断面来正确计算,但其余的横断面将生成NAs,然后整个结果向量将连接到每个组,而不仅仅是该子集的结果。

代码语言:javascript
运行
复制
library(data.table)
dt <- data.table(df)
dt[,f(X, Y), by = .(Transect, YYYY)]

使用dplyr也是一种选择,但同样,我不确定如何使它适用于不聚合数据的函数。

代码语言:javascript
运行
复制
library(dplyr)
df  %>%
  group_by(Transect, YYYY) %>%
  mutate(dist = f(X, Y))

上面的代码生成Error: Column 'dist' must be length 2 (the group size) or one, not 8

有什么想法吗?提前感谢!

EN

回答 1

Stack Overflow用户

发布于 2019-07-07 15:27:17

若要添加用于计算从端点位置(最小X坐标)到每个横断面年份编组中所有其他位置的欧几里德距离的列dist,可以执行以下操作:

代码语言:javascript
运行
复制
## data
df <- data.frame(
    Transect = c(rep(1,4),rep(2,4)),
    YYYY = c(2015,2015,2016,2016,2015,2015,2016,2016),
    X = seq(2,16, by = 2),
    Y = c(1,2,3,5,6,13,22,31))

## with dplyr
library(dplyr)

df %>%
    group_by(Transect, YYYY) %>%
    mutate(dist = sqrt((Y - Y[which.min(X)])^2 + (X - min(X))^2)) %>%
    ungroup()
#> # A tibble: 8 x 5
#>   Transect  YYYY     X     Y  dist
#>      <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1        1  2015     2     1  0   
#> 2        1  2015     4     2  2.24
#> 3        1  2016     6     3  0   
#> 4        1  2016     8     5  2.83
#> 5        2  2015    10     6  0   
#> 6        2  2015    12    13  7.28
#> 7        2  2016    14    22  0   
#> 8        2  2016    16    31  9.22

## with data.table
library(data.table)

setDT(df)[, dist := sqrt((Y - Y[which.min(X)])^2 + (X - min(X))^2), by = c("Transect", "YYYY")][]
#>    Transect YYYY  X  Y     dist
#> 1:        1 2015  2  1 0.000000
#> 2:        1 2015  4  2 2.236068
#> 3:        1 2016  6  3 0.000000
#> 4:        1 2016  8  5 2.828427
#> 5:        2 2015 10  6 0.000000
#> 6:        2 2015 12 13 7.280110
#> 7:        2 2016 14 22 0.000000
#> 8:        2 2016 16 31 9.219544
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56918563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档