我需要将多个计算应用于数据框中的一列。 为此,我提取了该列,创建了一个新的数据框,然后开始使用主要包含简单计算的新列来进行构建。 然后我需要对数据框中的每一列重复(相当长的脚本)。
应用族不起作用,因为我无法将所有计算都放到一个函数中(x)
我的原始数据帧如下所示,其中S是站点编号,值是生物量(1981:2007年和S1:S25年)。 我希望将下面的脚本应用于每个单独的列(每个站点),并为每个列使用单独的输出数据帧。
我的data.frame称为ts.bio,其中包含NA's
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))
我试图使用循环并应用家庭,但无能为力。创建一个函数(function(x))“套用”似乎很疯狂,因为脚本中有太多内容。
感谢sm的建议!对不起,很抱歉。
答案 0 :(得分:0)
我建议将您的数据从宽格式转换为长格式,然后使用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
这是原始格式的原始数据的结构。让我们将其更改为长格式并进行一些计算。
# 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
我错过了原始版本中的网站分组,现已更正。