Skip to content

Commit ecfa3f9

Browse files
committed
Merge branch 'functions'
seperated functions, avoid growing df
2 parents 8e897b1 + a34b462 commit ecfa3f9

1 file changed

Lines changed: 83 additions & 17 deletions

File tree

R/datplot_funs.R

Lines changed: 83 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,104 @@
1414

1515
datsteps <- function(df, stepsize = 5) {
1616
result <- as.data.frame(NULL)
17-
if (any(df[,3] > df[,4])) {
17+
if (any(df[,3] > df[,4]) == TRUE) {
1818
print(paste("Error: Dating seems to be in wrong order at ",
1919
df[which(df[,3] > df[,4]),1],
2020
" (Index: ", which(df[,3] > df[,4]), ")",
2121
". Please supply minimum date in 3rd Column, maximum date in 4th.", sep = ""))
2222
} else {
23-
df$weight <- abs(df[,3] - df[,4])
24-
if (any(df$weight == 0)) {
23+
weights <- get.weights(df[,3], df[,4])
24+
25+
26+
if (any(weights[,2] == FALSE)) {
2527
print(paste("Warning: DAT_min and DAT_max in ",
26-
df[which(df$weight == 0),1],
27-
" (Index: ", which(df$weight == 0), ")",
28+
df[which(weights == FALSE),1],
29+
" (Index: ", which(weights == FALSE), ")",
2830
" have the same value! Is this correct? Please check the table for possible errors.", sep = ""))
29-
df$weight[which(df$weight == 0)] <- 1
3031
}
31-
df$weight <- 1/df$weight
32-
for (i in 1:nrow(df)) {
33-
sequence <- NULL
32+
33+
df$weight <- weights[,1]
34+
result <- create.sub.objects(df, stepsize)
35+
}
36+
return(result)
37+
}
38+
39+
40+
#' Calculate the weights for each dated object
41+
#'
42+
#' Requires a dataframe with 4 variables: ID (ideally factor), group (ideally factor),
43+
#' minimum date (int/numeric) and maximum date (int/numeric). It's expected that dates BCE are
44+
#' displayed as negative values while dates CE are positive values. Ignoring this will cause problems
45+
#' in any case.
46+
#'
47+
#' @param DAT_min a vector containing the minimum date (int/num) of each object
48+
#' @param DAT_max a vector containing the maximum date (int/num) of each object
49+
#'
50+
#' @return the 'weight' value for the datsteps-dataframe, that is a quantification of how well the object is dated (lesser value means object is dated to larger timespans, i.e. with less confidence)
51+
#'
52+
#' @export get.weights
53+
54+
55+
get.weights <- function(DAT_min, DAT_max) {
56+
weights <- as.data.frame(matrix(ncol = 2, nrow = length(DAT_min)))
57+
weights[,1] <- abs(DAT_min - DAT_max)
58+
weights[,2] <- TRUE
59+
if (any(weights[,1] == 0)) {
60+
weights[which(weights[,1] == 0),2] <- FALSE
61+
weights[which(weights[,1] == 0),1] <- 1
62+
}
63+
weights[,1] <- 1/weights[,1]
64+
return(weights)
65+
}
66+
67+
#' Create sub-objects for each object in a dataframe
68+
#'
69+
#' Requires a dataframe with 5 variables: ID (ideally factor), group (ideally factor),
70+
#' minimum date (int/numeric), maximum date (int/numeric) and weight (as created by get.weights). It's expected that dates BCE are
71+
#' displayed as negative values while dates CE are positive values. Ignoring this will cause problems
72+
#' in any case.
73+
#'
74+
#' @param df a dataframe with 4 variable: ID, group, minimum date (int/num) maximum date (int/num), _must_ be in this order, colnames are irrelevant; each object _must_ be one row.
75+
#' @param stepsize defaults to 5. Number of years that should be used as an interval for creating dating steps.
76+
#'
77+
#' @return a larger dataframe with a number of steps for each object as well as a 'weight' value, that is a quantification of how well the object is dated (lesser value means object is dated to larger timespans, i.e. with less confidence)
78+
#'
79+
#' @export create.sub.objects
80+
81+
# this could be optimizes, maybe with apply()? because it takes too long
82+
create.sub.objects <- function(df, stepsize) {
83+
84+
mean_year_index <- which(df[,4]-df[,3] < stepsize)
85+
86+
outputnr <- ceiling(sum(((abs(df[-mean_year_index,3]-df[-mean_year_index,4]))/stepsize)+1))
87+
outputnr <- outputnr+length(mean_year_index)
88+
89+
result <- as.data.frame(matrix(ncol = ncol(df)+1, nrow = outputnr))
90+
91+
colnames(result) <- c(colnames(df), "DAT_step")
92+
for (i in 1:nrow(df)) {
93+
sequence <- NULL
94+
if ((df[i,4]-df[i,3]) < stepsize) {
95+
print(paste("stepsize is larger than the range of the closest dated object: ",
96+
df[i,1], " (Index = ", i, "). Using mean as year.", sep = ""))
97+
sequence <- (df[i,3]+df[i,4])/2
98+
} else {
3499
sequence <- seq(df[i,3], df[i,4], by = stepsize)
35-
length <- length(sequence)
36-
for (zahl in sequence) {
37-
wip <- df[i,]
38-
wip$DAT_Step <- zahl
39-
wip$weight <- wip$weight / length(sequence)
40-
result <- rbind(result, wip)
41-
}
100+
}
101+
length <- length(sequence)
102+
for (step in sequence) {
103+
wip <- df[i,]
104+
wip$DAT_Step <- step
105+
wip$weight <- wip$weight / length(sequence)
106+
first_na <- match(NA, result$ID)
107+
result[first_na,] <- wip[,]
42108
}
43109
}
110+
result <- result[-c(match(NA, result$ID):nrow(result)), ]
44111
return(result)
45112
}
46113

47114

48-
49115
#' Scales the content of the weight columns according to group membership
50116
#'
51117
#' Requires a dataframe as produced by datsteps(). (Meaning 6 columns in the following order: ID, group, minimum/earliest date, maximum/latest date, weight, 'DAT_Steps')

0 commit comments

Comments
 (0)