在数据框中,我试图计算地层列中特定间隔处的总厚度,并在数据框中创建这些总厚度的新汇总。我是r的新手,我正在努力如何在列中添加连续值。
任何帮助或见识将不胜感激。甚至是建议的阅读材料或帮助页面。
我正在尝试计算地层柱特定床的顶部和底部。本质上,是地层列中特定间隔处的总厚度。我有每张床的厚度,我想计算顶部和底部相对于整列底部的位置。我一直在努力想出一个解决方案,我觉得我根本不了解足够的功能和命令来让我编写满足我需要的代码。我还认为我可能需要创建一个函数才能执行所需的操作。
这是我开始使用的数据。岩性或岩石类型,以及每个岩床或岩石类型的总厚度。最后一行是地层柱的绝对基准,因此没有厚度。
Lithology Thickness
sand 4
mud 1
sand 5
mud 3
mud 5
sand 2
bottom 0
我希望做的是创建两个新列,在其中我计算每种岩石类型的高度/顶部和每种岩石类型的基础,最后得到一个像下面的数据框。
我想添加/求和厚度以计算每种岩性的顶部和底部,并参考底部。
因此,要计算中砂的顶部,我想对包括中砂在内的所有先前岩性的厚度求和。然后要计算基数,我想对除中间砂层以外的所有先前岩性的厚度求和。我想对每种岩性都这样做。
Lithology Thickness Top Base
sand 4 20 16
mud 1 16 15
sand 5 15 10
mud 3 10 7
mud 5 7 2
sand 2 2 0
bottom 0 0 0
非常感谢您的帮助,谢谢您的宝贵时间!
答案 0 :(得分:3)
在这些替代方案中,我们使用在末尾的注释中可重复显示的输入。
内的 1)是厚度的总和减去我们可以使用cumsum
计算的那一点的厚度。最上面是加上当前的厚度。不使用任何软件包。
within(DF, {
Base <- sum(Thickness) - cumsum(Thickness)
Top <- Base + Thickness
})
给予:
Lithology Thickness Top Base
1 sand 4 20 16
2 mud 1 16 15
3 sand 5 15 10
4 mud 3 10 7
5 mud 5 7 2
6 sand 2 2 0
7 bottom 0 0 0
2)变换 Top
是总厚度减去到该点为止的厚度(当前厚度除外)。除最后一项外,基础均相同。不使用任何软件包。
transform(DF,
Top = sum(Thickness) - cumsum(Thickness) + Thickness,
Base = sum(Thickness) - cumsum(Thickness))
2a)为了利用先前的计算,我们可以迭代transform
:
transform(
transform(DF, Top = sum(Thickness) - cumsum(Thickness) + Thickness),
Base = Top - Thickness)
2b)或这样做:
Base <- with(DF, sum(Thickness) - cumsum(Thickness))
transform(DF, Top = Base + Thickness, Base = Base)
3)dplyr 使用dplyr,每个组件都可以使用已经在左侧完成的计算,因此可以编写:
library(dplyr)
DF %>%
mutate(Top = sum(Thickness) - cumsum(Thickness) + Thickness,
Base = Top - Thickness)
4)gsubfn 在gsubfn程序包中使用transform2
可以计算出每个组件依赖于其他任何组件,它将自动确定依赖性并以正确的顺序执行计算。
library(gsubfn)
transform2(DF,
Top = Base + Thickness,
Base = sum(Thickness) - cumsum(Thickness))
Lines <- "Lithology Thickness
sand 4
mud 1
sand 5
mud 3
mud 5
sand 2
bottom 0"
DF <- read.table(text = Lines, header = TRUE, as.is = TRUE)
答案 1 :(得分:3)
您需要的功能是cumsum
。顾名思义,它创建了累加和。
您需要首先反转return
数据(以便从底层开始),生成累积和,然后反转(以正确的顺序放回去)。
Thickness
这将生成:
data$Top = rev( cumsum( rev(data$Thickness) ) )
Lithology Thickness Top
sand 4 20
mud 1 16
sand 5 15
mud 3 10
mud 5 7
sand 2 2
bottom 0 0
值不过是上移的Base
值。这样您就可以轻松做到:
Top
然后您的数据框变为:
data$Base = c( data$Top[ 2:length(data$Top) ] , 0)
答案 2 :(得分:2)
我们可以使用dplyr
包来实现此目的。 lead
函数可以将数据转发。
library(dplyr)
dat2 <- dat %>%
mutate(Top = rev(cumsum(rev(Thickness)))) %>%
mutate(Base = lead(Top, default = 0))
dat2
# Lithology Thickness Top Base
# 1 sand 4 20 16
# 2 mud 1 16 15
# 3 sand 5 15 10
# 4 mud 3 10 7
# 5 mud 5 7 2
# 6 sand 2 2 0
# 7 bottom 0 0 0
数据
dat <- read.table(text = "Lithology Thickness
sand 4
mud 1
sand 5
mud 3
mud 5
sand 2
bottom 0",
header = TRUE, stringsAsFactors = FALSE)