首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将包含多个计算的整个脚本应用于data.frame中的每一列

如何将包含多个计算的整个脚本应用于data.frame中的每一列
EN

Stack Overflow用户
提问于 2019-04-26 10:28:18
回答 1查看 40关注 0票数 0

我需要将大量的计算应用于数据帧中的一列。为此,我提取列,创建一个新的数据框架,然后使用主要包含简单计算的新列开始构建。然后,我需要对数据帧中的每一列重复这个(相当长的脚本)。

应用家族无法工作,因为我无法将所有的计算都放在一个函数(X)中

我最初的数据框架是这样的,其中S是站点号,值是生物量( 1981:2007和S1:S25站点)。我希望下面的脚本适用于每一列(每个站点)和一个单独的输出数据帧每列。

我的data.frame叫做ts.bio,它包括NA的

代码语言:javascript
运行
复制
    year S1 S2 S3  S4  S5  S6  S7 S8  S9 S10 S11 S12 S13 S14 S15
    1981 94 91 92 103 162 104 125 91 108 101 117 138 115  95  99
    1982 33 52 52  73 109  40  41 55  51  77  77 100  54  44  62
    1983 26 14 30  29  46  14  16 25  11  24  31  31  19  11  28

这是我需要应用于每一列的脚本。

代码语言:javascript
运行
复制
    change<-NULL

    for (i in 1881:2007){
      lambda<-tsBio$S1[tsBio$year==i+1]/tsBio$S1[tsBio$year==i]
      change<-c(change, lambda)
         }


    print(change)

    #edit the data frame 
    change<-as.data.frame(change)  
    change$t<-c(1:26)    #add time 
    change$year<-c(1982:2007)   #add year 

    # I need DataCombine for the Insert Row line 
    library("DataCombine")
    NewRow<-c(0, 0, 1981)   #create new row
    change<-InsertRow(change, NewRow, RowNum=1) #ad new row

    change$biomass<- tsBio$S1   #add population size


    #create a lagged version to compute delta for differentiated B      (B')
    change$changelag<-change$change #duplicate column
    change$biomasslag<-change$biomass #duplicate column 
    change$tlag<-change$t


    #before this I need to detach dataCombine and activate data.table
    detach("package:DataCombine", unload=TRUE)
    library("data.table")
    change$changelag<-shift(change$changelag, n=1, type="lag")
    change$biomasslag<-shift(change$biomasslag, n=1, type="lag")
    change$tlag<-shift(change$tlag, n=1, type="lag")


    #compute nominator and denominator of differentiated B (B')
    change$deltaB<-(change$change-change$changelag)
    change$deltaX<- (change$biomass - change$biomasslag)

    change$Bdiff<-(change$deltaB/change$deltaX) 

    #compute mortality differentiated
    change$deltat<-(change$t-change$tlag)
    change$M<- change$change-(change$deltaX/change$deltat)

    change$Mdiff<-(change$M/change$biomass)

    change$lambda<-(change$Bdiff-change$Mdiff)

    library("ggplot2")
     ggplot(data=change, aes(x=year))+
     geom_point(aes(y=lambda))

我试着使用循环和应用家庭,但什么也做不了。创建一个函数(函数(X))来"lapply“似乎很疯狂,因为脚本中有太多的内容。

谢谢您的建议!为你的沉默而道歉。

EN

回答 1

Stack Overflow用户

发布于 2019-04-26 11:08:28

我建议将数据从宽格式转换为长格式,然后使用dplyr。在这种情况下,每一行将是一个观察,并将有一个列的年份,地点#,兰巴达,生物量等,它将保存所有的数据在一个单一的方便的数据框架。提取某些站点、年份等的数据很容易使用filter。下面是一个例子:

代码语言:javascript
运行
复制
# Create dummy data frame
df <- data.frame(year = 1981:2007,
                 t = 1:27,
                 S1 = sample(1:200, 27, replace = TRUE),
                 S2 = sample(1:200, 27, replace = TRUE),
                 S3 = sample(1:200, 27, replace = TRUE),
                 S4 = sample(1:200, 27, replace = TRUE),
                 S5 = sample(1:200, 27, replace = TRUE))

# Quick peak
head(df)
#>   year t  S1  S2  S3  S4  S5
#> 1 1981 1 163 133  86  59  40
#> 2 1982 2  99  28 190 179  58
#> 3 1983 3  94 136   6  47 185
#> 4 1984 4 199  87 137  31  20
#> 5 1985 5 157 169 172  24  21
#> 6 1986 6 105  33 189 122 148

这是宽格式原始数据的结构。让我们将其更改为long格式,并进行一些计算。

代码语言:javascript
运行
复制
# Load libraries
library(dplyr)
library(magrittr)
library(tidyr)


# 1) Convert to long format
# 2) Group by site for calculations
# 3) Calculate lambda, change in biomass
# 4) Ungroup
df %<>% 
  gather(site, biomass, S1:S5) %>% 
  group_by(site) %>% 
  mutate(lambda = biomass/lag(biomass),
         delta_biomass = biomass - lag(biomass)) %>% 
  ungroup

# Quick peak
head(df)
# # A tibble: 6 x 6
#    year     t site  biomass  lambda delta_biomass
#   <int> <int> <chr>   <int>   <dbl>         <int>
# 1  1981     1 S1        175 NA                 NA
# 2  1982     2 S1         74  0.423           -101
# 3  1983     3 S1        177  2.39             103
# 4  1984     4 S1         15  0.0847          -162
# 5  1985     5 S1         28  1.87              13
# 6  1986     6 S1        150  5.36             122

现在您的数据是长格式的,我们使用mutate进行了一些计算,它只是向数据帧中添加了一些列。(它还可以覆盖列。)注意,我不必在计算中创建任何中间滞后列,我只是使用了lag。通过这种方式,您可以添加所有的计算,而不需要任何循环,这样可以生成干净的、可读的代码。此外,像这样重新构造数据意味着您不必对每个站点列执行此操作,因为它同时应用于所有列。

起初,将所有这些数据放在一个地方似乎很麻烦,但实际上使用filter从其中提取想要的数据是非常容易的。例如:

代码语言:javascript
运行
复制
# Only see data for site S4 between 2000 and 2005
df %>% 
  filter(site == "S4", 
         between(year, 2000, 2005))
# # A tibble: 6 x 6
#     year     t site  biomass lambda delta_biomass
#    <int> <int> <chr>   <int>  <dbl>         <int>
# 1  2000    20 S4        124  1.38             34
# 2  2001    21 S4        116  0.935            -8
# 3  2002    22 S4        178  1.53             62
# 4  2003    23 S4         92  0.517           -86
# 5  2004    24 S4        107  1.16             15
# 6  2005    25 S4         87  0.813           -20

编辑

我错过了原版本中的站点分组,现在已经更正了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55865665

复制
相关文章

相似问题

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