我需要将大量的计算应用于数据帧中的一列。为此,我提取列,创建一个新的数据框架,然后使用主要包含简单计算的新列开始构建。然后,我需要对数据帧中的每一列重复这个(相当长的脚本)。
应用家族无法工作,因为我无法将所有的计算都放在一个函数(X)中
我最初的数据框架是这样的,其中S是站点号,值是生物量( 1981:2007和S1:S25站点)。我希望下面的脚本适用于每一列(每个站点)和一个单独的输出数据帧每列。
我的data.frame叫做ts.bio,它包括NA的
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这是我需要应用于每一列的脚本。
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“似乎很疯狂,因为脚本中有太多的内容。
谢谢您的建议!为你的沉默而道歉。
发布于 2019-04-26 11:08:28
我建议将数据从宽格式转换为长格式,然后使用dplyr。在这种情况下,每一行将是一个观察,并将有一个列的年份,地点#,兰巴达,生物量等,它将保存所有的数据在一个单一的方便的数据框架。提取某些站点、年份等的数据很容易使用filter。下面是一个例子:
# 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格式,并进行一些计算。
# 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从其中提取想要的数据是非常容易的。例如:
# 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编辑
我错过了原版本中的站点分组,现在已经更正了。
https://stackoverflow.com/questions/55865665
复制相似问题