Introduction

This report explores patterns within reported UFO sightings. The current analysis focuses on whether the time of day a UFO sighting occurs is associated with the duration of the sighting:

Research Question

Is the time of day a UFO sighting occurs associated with the duration of the the sighting?

Hypothesis

UFO sighting duration is associated with the time of day when the sighting occurs.

Data Preparation

Loading the Dataset

The UFO sightings dataset is stored as a CSV file within the project’s data folder. The following code loads the dataset into R for analysis.

ufo <- read.csv("data/ufo_sightings.csv")

Inspect the data

How many rows and columns dose this data set contain?

dim(ufo)
## [1] 80332    11

What are the column labels?

names(ufo)
##  [1] "datetime"             "city"                 "state"               
##  [4] "country"              "shape"                "duration..seconds."  
##  [7] "duration..hours.min." "comments"             "date.posted"         
## [10] "latitude"             "longitude"

Look at the first 10 rows.

head(ufo, 10)
##               datetime                 city state country    shape
## 1  1949-10-10 20:30:00           san marcos    tx      us cylinder
## 2  1949-10-10 21:00:00         lackland afb    tx            light
## 3  1955-10-10 17:00:00 chester (uk/england)            gb   circle
## 4  1956-10-10 21:00:00                 edna    tx      us   circle
## 5  1960-10-10 20:00:00              kaneohe    hi      us    light
## 6  1961-10-10 19:00:00              bristol    tn      us   sphere
## 7  1965-10-10 21:00:00   penarth (uk/wales)            gb   circle
## 8  1965-10-10 23:45:00              norwalk    ct      us     disk
## 9  1966-10-10 20:00:00            pell city    al      us     disk
## 10 1966-10-10 21:00:00             live oak    fl      us     disk
##    duration..seconds. duration..hours.min.
## 1                2700           45 minutes
## 2                7200              1-2 hrs
## 3                  20           20 seconds
## 4                  20             1/2 hour
## 5                 900           15 minutes
## 6                 300            5 minutes
## 7                 180         about 3 mins
## 8                1200           20 minutes
## 9                 180           3  minutes
## 10                120      several minutes
##                                                                                                                                                      comments
## 1                     This event took place in early fall around 1949-50. It occurred after a Boy Scout meeting in the Baptist Church. The Baptist Church sit
## 2                                                             1949 Lackland AFB&#44 TX.  Lights racing across the sky &amp; making 90 degree turns on a dime.
## 3                                                                                                         Green/Orange circular disc over Chester&#44 England
## 4                  My older brother and twin sister were leaving the only Edna theater at about 9 PM&#44...we had our bikes and I took a different route home
## 5  AS a Marine 1st Lt. flying an FJ4B fighter/attack aircraft on a solo night exercise&#44 I was at 50&#44000&#39 in a &quot;clean&quot; aircraft (no ordinan
## 6                  My father is now 89 my brother 52 the girl with us now 51 myself 49 and the other fellow which worked with my father if he&#39s still livi
## 7                          penarth uk  circle  3mins  stayed 30ft above me for 3 mins slowly moved of and then with the blink of the eye the speed was unreal
## 8                                           A bright orange color changing to reddish color disk/saucer was observed hovering above power transmission lines.
## 9                                     Strobe Lighted disk shape object observed close&#44 at low speeds&#44 and low altitude in Oct 1966 in Pell City Alabama
## 10                                                           Saucer zaps energy from powerline as my pregnant mother receives mental signals not to pass info
##    date.posted   latitude   longitude
## 1   2004-04-27 29.8830556  -97.941111
## 2   2005-12-16   29.38421  -98.581082
## 3   2008-01-21       53.2   -2.916667
## 4   2004-01-17 28.9783333  -96.645833
## 5   2004-01-22 21.4180556 -157.803611
## 6   2007-04-27     36.595  -82.188889
## 7   2006-02-14  51.434722   -3.180000
## 8   1999-10-02    41.1175  -73.408333
## 9   2009-03-19 33.5861111  -86.286111
## 10  2005-05-11 30.2947222  -82.984167

from the head we can see that there are some missing values in the state and country. It dose not affect our current target, but it is worth noting.

What are the variables?

str(ufo)
## 'data.frame':    80332 obs. of  11 variables:
##  $ datetime            : chr  "1949-10-10 20:30:00" "1949-10-10 21:00:00" "1955-10-10 17:00:00" "1956-10-10 21:00:00" ...
##  $ city                : chr  "san marcos" "lackland afb" "chester (uk/england)" "edna" ...
##  $ state               : chr  "tx" "tx" "" "tx" ...
##  $ country             : chr  "us" "" "gb" "us" ...
##  $ shape               : chr  "cylinder" "light" "circle" "circle" ...
##  $ duration..seconds.  : chr  "2700" "7200" "20" "20" ...
##  $ duration..hours.min.: chr  "45 minutes" "1-2 hrs" "20 seconds" "1/2 hour" ...
##  $ comments            : chr  "This event took place in early fall around 1949-50. It occurred after a Boy Scout meeting in the Baptist Church"| __truncated__ "1949 Lackland AFB&#44 TX.  Lights racing across the sky &amp; making 90 degree turns on a dime." "Green/Orange circular disc over Chester&#44 England" "My older brother and twin sister were leaving the only Edna theater at about 9 PM&#44...we had our bikes and I "| __truncated__ ...
##  $ date.posted         : chr  "2004-04-27" "2005-12-16" "2008-01-21" "2004-01-17" ...
##  $ latitude            : chr  "29.8830556" "29.38421" "53.2" "28.9783333" ...
##  $ longitude           : num  -97.94 -98.58 -2.92 -96.65 -157.8 ...

From this probe we find the columns that we wish to use mathematical analysis on are Chr data types and will need to be changed before they can be useful.

Persevere the data

To make sure the original data is perverse before changing the original structure we will make a copy. This will prevent any of the orginal infomation from getting lost. Did the duration..seconds. column become a char because some values have 30 sec in a few records? If so would the conversion delete those rows.

I do not know so we will error on the side of safe and create a copy. Therefore

orginal database -> ufo cleaned database -> ufo_clean

ufo_clean <- ufo

Convert The Data

Here we will start with converting the duration_seconds to numeric

ufo_clean$duration_seconds <- as.numeric(ufo_clean$duration..seconds.)
## Warning: NAs introduced by coercion

In doing this We see the Warning message: NAs introduced by coercion this means some of the data has been changed into NA’s. let’s see how many were affected.

sum(is.na(ufo_clean$duration_seconds))
## [1] 3

We see 3 How many of the original data had NA’s?

sum(is.na(ufo$duration..seconds.))
## [1] 0

Although I no do think that is enough information to be worried about, I want to see what is causing this issue.

ufo_clean$duration..seconds.[is.na(ufo_clean$duration_seconds) & !is.na(ufo_clean$duration..seconds.)]
## [1] "2`"   "8`"   "0.5`"

It looks like we are very lucky were the same typo appears for each. Here we Will get rid of the ` mark

ufo_clean$duration_seconds <- as.numeric(
  gsub("`", "", ufo_clean$duration..seconds.))

Checking to see if it worked

sum(is.na(ufo_clean$duration_seconds))
## [1] 0

Great! it worked let’s peek at what the data is telling us about the duration.

summary(ufo_clean$duration_seconds)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##        0       30      180     9017      600 97836000

There are a few things that are worth thinking about when we look at the summary of time. + How is there a duration of 0 seconds + How is the max time of 97,836,000 seconds / 3.1 years + The median is 180 but the mean is 9,017 (is that skewed by the max?) + 75% of the sightings are less than 600 seconds/ 10 minutes

It is highly likely that this data will not have a normal distribution given that the mean and median are a magnitude of order different from each other. This could mean that the traditional t-test is not the best option.

datetime data conversion We just completed the data conversion for the duration in seconds now we need to begin with the date time. Converting it to a numeric I would like to also separate out all of the information in this one column. Currently it has a format of date, hour, min, seconds. I will need the hour to determine if it is day or night for this current hypothesis, my next hypothesis will need the year, and the third will need the month.

The plan is to do the following

datetime original information sighting_datetime properly converted R date-time sighting_date date only year 1949 month 10 hour 20 duration_seconds numeric duration —> this is done

For sighting_datetime I found POSIXct to use exatly for this

ufo_clean$sighting_datetime <- as.POSIXct(ufo_clean$datetime, format = "%Y-%m-%d %H:%M:%S")

Check to see if it worked

class(ufo_clean$sighting_datetime)
## [1] "POSIXct" "POSIXt"

Just like for the seconds I did some investigation of the data to see if there were any NA’s that were not there before. This time 4 were found, after further investigation the 4 NA occurred because of daylight savings time. The “easy fix” for this is to tell R to not apply the computer;s Eastern-time daylight-saving rules

ufo_clean$sighting_datetime <- as.POSIXct(
    ufo_clean$datetime,
    format = "%Y-%m-%d %H:%M:%S",
    tz = "UTC"
)

Moving on to create our date, year, month and hour

ufo_clean$sighting_date <- as.Date(ufo_clean$sighting_datetime)

ufo_clean$year <- as.integer(
  format(ufo_clean$sighting_datetime, "%Y")
)

ufo_clean$month <- as.integer(
  format(ufo_clean$sighting_datetime, "%m")
)

ufo_clean$hour <- as.integer(
  format(ufo_clean$sighting_datetime, "%H")
)

Check it to make sure it worked

head(
  ufo_clean[
    c("datetime", "sighting_date", "year", "month", "hour",
      "duration_seconds")
  ],
  10
)
##               datetime sighting_date year month hour duration_seconds
## 1  1949-10-10 20:30:00    1949-10-10 1949    10   20             2700
## 2  1949-10-10 21:00:00    1949-10-10 1949    10   21             7200
## 3  1955-10-10 17:00:00    1955-10-10 1955    10   17               20
## 4  1956-10-10 21:00:00    1956-10-10 1956    10   21               20
## 5  1960-10-10 20:00:00    1960-10-10 1960    10   20              900
## 6  1961-10-10 19:00:00    1961-10-10 1961    10   19              300
## 7  1965-10-10 21:00:00    1965-10-10 1965    10   21              180
## 8  1965-10-10 23:45:00    1965-10-10 1965    10   23             1200
## 9  1966-10-10 20:00:00    1966-10-10 1966    10   20              180
## 10 1966-10-10 21:00:00    1966-10-10 1966    10   21              120

Since we have the hours out lets see how many sightings by hour

table(ufo_clean$hour)
## 
##     0     1     2     3     4     5     6     7     8     9    10    11    12 
##  4802  3210  2357  2004  1529  1591  1224   905   803   958  1166  1144  1368 
##    13    14    15    16    17    18    19    20    21    22    23 
##  1303  1322  1433  1620  2592  4002  6147  8617 11445 10837  7953

Looking at this let divide this into 4 sections

Overnight 0–5 Morning 6–11 Afternoon 12–17 Evening 18–23

ufo_clean$time_period <- cut(
  ufo_clean$hour,
  breaks = c(-1, 5, 11, 17, 23),
  labels = c("Overnight", "Morning", "Afternoon", "Evening")
)

Let’s look at this in a table form

table(ufo_clean$time_period)
## 
## Overnight   Morning Afternoon   Evening 
##     15493      6200      9638     49001

Viewing the data

Remember how the mean and median were very different and the max value was much larger than the 3rd quarter/75% of the data? Spoiler alert I looked at the max data’s description. The description stated that it was only a few seconds. Most likely it is a typo, but reading 80k plus descriptions is a bit much, so lets see if math can help.

ggplot(ufo_clean, aes(x = time_period, y = duration_seconds / 60)) +
  geom_boxplot() +
  labs(
    title = "UFO Sighting Duration by Time of Day",
    x = "Time of Day",
    y = "Duration (Minutes)"
  )

Question 1

I am going to start with grouping the hourly duration using the dplyr library. We should expect to see 24 groups

hourly_duration <- ufo_clean %>% group_by(hour) %>% summarise(median_duration_seconds = median(median(duration_seconds)))

dim(hourly_duration)
## [1] 24  2

Let’s add a row for munitues

hourly_duration <- ufo_clean %>%
  group_by(hour) %>%
  summarise(median_duration_seconds = median(duration_seconds)
  ) %>%
  mutate(median_duration_minutes = median_duration_seconds / 60)

print(hourly_duration, n = 24)
## # A tibble: 24 × 3
##     hour median_duration_seconds median_duration_minutes
##    <int>                   <dbl>                   <dbl>
##  1     0                     180                       3
##  2     1                     180                       3
##  3     2                     180                       3
##  4     3                     180                       3
##  5     4                     180                       3
##  6     5                     180                       3
##  7     6                     180                       3
##  8     7                     180                       3
##  9     8                     180                       3
## 10     9                     180                       3
## 11    10                     180                       3
## 12    11                     180                       3
## 13    12                     180                       3
## 14    13                     120                       2
## 15    14                     180                       3
## 16    15                     180                       3
## 17    16                     180                       3
## 18    17                     180                       3
## 19    18                     180                       3
## 20    19                     180                       3
## 21    20                     180                       3
## 22    21                     180                       3
## 23    22                     180                       3
## 24    23                     180                       3

I decided to go with the box plot and use a log10 scale because we have observed that there is a large right tail to this dataset that can still be useful.

ggplot(ufo_clean, aes(x = time_period, y = duration_seconds / 60)) +
  geom_boxplot() +
  scale_y_log10() +
  labs(
    title = "UFO Sighting Duration by Time of Day",
    x = "Time of Day",
    y = "Duration (Minutes, Log Scale)"
  )

The boxplot shows that the median UFP sighting duration is similar across the four time periods. However, there is some variation in the interquartile ranges (between Q1 and Q3), with overnight sightings showing a wider spread in the middle 50% of reported duration. the distributions are also strongly right-skewed, with many high-duration outliers across the four time periods.

The logarithmic scal is used because the repoted UPF sighting duration spans a very large range. on the y-axis each increase represents an order of magnitude. This allows the more abundent short duration sightingd to remain visible withour being compressed by the small number of extermely long-duration sightings.

Question 2

duration_summary <- ufo_clean %>%
  group_by(time_period) %>%
  summarise(
    count = n(),
    Q1_minutes = quantile(duration_seconds / 60, 0.25),
    median_minutes = median(duration_seconds / 60),
    Q3_minutes = quantile(duration_seconds / 60, 0.75),
    IQR_minutes = IQR(duration_seconds / 60)
  )

duration_summary
## # A tibble: 4 × 6
##   time_period count Q1_minutes median_minutes Q3_minutes IQR_minutes
##   <fct>       <int>      <dbl>          <dbl>      <dbl>       <dbl>
## 1 Overnight   15493        0.5              3         15        14.5
## 2 Morning      6200        0.5              3         10         9.5
## 3 Afternoon    9638        0.5              3         10         9.5
## 4 Evening     49001        0.5              3         10         9.5

Although the median reported sighting duration is 3 for all four time periods the larger interquartile range(IQR) is seen in the overnight as seen in the previous boxplot.

with that in mind the IQR/variability is easier to see in the chart below. It dose not mean that the sightings are longer, it only means that there is more variability during this time range.

ggplot(duration_summary,
       aes(x = time_period, y = IQR_minutes)) +
  geom_col() +
  labs(
    title = "Variation in UFO Sighting Duration by Time of Day",
    x = "Time of Day",
    y = "Interquartile Range (Minutes)"
  )

Question 3

For question 3 we are asking “Is there a measurable statistical relationship between time of day and sighting duration?”. for this questions we will look deeper into correlation, R^2, p-value, scatterplot and regression line. this section will be a little different because of the large duration times. like with the box plot using the log10 scale so the right tail dose not dominate the data we will use the log10 scale for the regression process as well.

lets look at one of the main differences when interpenetrating the data. Notice how the median is not 3 like we previously calulated or is it?

It is because we are looking at the log10 format the data is based off of log 10. so if you take 10^2.255273 is about 180 seconds which is the 3 minutes. Likewise when you see the -3 that is 0.001 seconds. This is very useful and needed because our values span over orders of magnitude. So we are thinking about the ratios rather than enormous absolute differences.

# Log-transform sighting duration to reduce the effect of extreme right-skew
ufo_clean$log_duration <- log10(ufo_clean$duration_seconds)

summary(ufo_clean$log_duration)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  -3.000   1.477   2.255   2.150   2.778   7.990

Apply correlation

let’s take a look at the correlation

duration_correlation <- cor.test(
  ufo_clean$hour,
  ufo_clean$log_duration,
  method = "pearson"
)

duration_correlation
## 
##  Pearson's product-moment correlation
## 
## data:  ufo_clean$hour and ufo_clean$log_duration
## t = -3.7533, df = 80330, p-value = 0.0001747
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  -0.020154660 -0.006326677
## sample estimates:
##        cor 
## -0.0132413

First we see that the correlation number is r = -0.01324. with the Pearson’s model it ranges from -1 to 1 where 0 represents no relationship. since we are really close to 0 the negative linear relationship is essentially negligible. Interesting the p value is 0.0001747 where the significance level is 0.05, so this says that the correlation is statistically significant. The negative linear relationship is extremely week. Therefore, the hour of day explains very little of the variation in sighting duration through a simple linear relationship.

R^2

(-0.0132413 )^2*100
## [1] 0.0175332

This shows the hour of day explains only 0.018% of the variation in log-transformed UFO sighting duration within this linear model. This meas that the linear model dose not fit, but it dose not yet prove the theory wrong.

##Scatter plot

ggplot(
  ufo_clean,
  aes(x = hour, y = log_duration)
) +
  geom_jitter(
    width = 0.2,
    height = 0,
    alpha = 0.05
  ) +
  geom_smooth(
    method = "lm",
    se = FALSE
  ) +
  labs(
    title = "Relationship Between Time of Day and UFO Sighting Duration",
    x = "Hour of Day",
    y = "Log10 Sighting Duration (Seconds)"
  )
## `geom_smooth()` using formula = 'y ~ x'

The Pearson correlation and simple linear regression were used to examine the relationship between hour of day and log10- transformed UFO sighting duration. The correlation was statistically significant (r = -0.0132, p = 0.0001747), but the magnitude of the relationship was extremely weak. The linear regression produced an R^2 of 0.000175. that indicated that our hour of day explained approximately 0.018% of the variation in the log-transformed sighting duration. The scatterplot supports this result, as the regression line is essentially horizontal and no strong linear pattern is visible.

Therefore, although the relationship is statistically significant, the results provide little evidence of a meaningful linear relationship between hour of day and sighting duration

Question 4

Here is a histogram using the log10 so the small number of long duration numbers do not over power the average UFO sightings numbers. As we saw earlier the data transformation is more balanced than the original data but it is not perfectly symmetric and the right tail remains. Several peaks are also visible, which may reflect the tendency for reported sighting duration to occur at a common rounded values.

ggplot(ufo_clean, aes(x = log_duration)) +
  geom_histogram(bins = 48) +
  labs(
    title = "Distribution of Log-Transformed UFO Sighting Durations",
    x = "Log10 of Sighting Duration (Seconds)",
    y = "Number of Sightings"
  )

Let’s take a look with more bins

ggplot(ufo_clean, aes(x = log_duration)) +
  geom_histogram(bins = 75) +
  labs(
    title = "Distribution of Log-Transformed UFO Sighting Durations",
    x = "Log10 of Sighting Duration (Seconds)",
    y = "Number of Sightings"
  )

Question 5

For this section I am going to divide the data into two groups.

ufo_clean$day_night <- ifelse(
  ufo_clean$hour >= 6 & ufo_clean$hour < 18,
  "Day",
  "Night"
)

ufo_clean$day_night <- factor(
  ufo_clean$day_night,
  levels = c("Day", "Night")
)

table(ufo_clean$day_night)
## 
##   Day Night 
## 15838 64494

Since we already know that the data is right skew we might need to continue with log10 transformations.From the simple count table we can see that about 80% of the sightings are in the nigth group. However we should look at how the data looks in the groups before deciding.

day_night_summary <- ufo_clean %>%
  group_by(day_night) %>%
  summarise(
    count = n(),
    median_minutes = median(duration_seconds / 60),
    mean_minutes = mean(duration_seconds / 60),
    IQR_minutes = IQR(duration_seconds / 60),
    mean_log_duration = mean(log_duration),
    sd_log_duration = sd(log_duration)
  )

day_night_summary
## # A tibble: 2 × 7
##   day_night count median_minutes mean_minutes IQR_minutes mean_log_duration
##   <fct>     <int>          <dbl>        <dbl>       <dbl>             <dbl>
## 1 Day       15838              3         158.         9.5              2.12
## 2 Night     64494              3         148.         9.5              2.16
## # ℹ 1 more variable: sd_log_duration <dbl>
ggplot(
  ufo_clean,
  aes(x = day_night, y = log_duration)
) +
  geom_boxplot() +
  labs(
    title = "Log-Transformed UFO Sighting Duration: Day vs. Night",
    x = "Time Period",
    y = "Log10 of Sighting Duration (Seconds)"
  )

We see that the data is remarkably similar in the typical duration, (again).

*Standard*

** Mean**

Median has the same for both day and night at 3mins. We found this earlier, where the differences between the mean and median highlights how the extreme duration affect the raw data.

*log transformation*

Mean

Log Standard Deviation.

Given this information I will move forward with the Welch two-sample t-test, we are handling unequal group sizes and doesn’t require us to assume the two populations have equal variances.

Our Hypotheses

The null hypothesis is:

\[ H_0: \mu_{Day} = \mu_{Night} \]

The alternative hypothesis is:

\[ H_A: \mu_{Day} \neq \mu_{Night} \]

Running the Test

day_night_ttest <- t.test(
  log_duration ~ day_night,
  data = ufo_clean
)

day_night_ttest
## 
##  Welch Two Sample t-test
## 
## data:  log_duration by day_night
## t = -4.4325, df = 24983, p-value = 9.353e-06
## alternative hypothesis: true difference in means between group Day and group Night is not equal to 0
## 95 percent confidence interval:
##  -0.05251195 -0.02031007
## sample estimates:
##   mean in group Day mean in group Night 
##            2.121021            2.157432

As you can see The Welch t-tesr gave us:

t=-4.4325, and p=9.353x10^-6

Since p<0.05 We reject the null hypotheses that the Day and Night groups have equal mean log-transformed durations. but we also need to look at the size of the difference before knowing what this test is actually telling us.

Mean

  • Day = 2.121021
  • Night = 2.157432

Therefore Day-Night = -0.036411, The negative t-statistic, But remember we are using log transformation so we must take a look at

10^0.036411
## [1] 1.087454

This is telling us the geometric-mean duration for Night is approximately 1.087 times the Day value an increase of 8.7%. Again this is not the whole story because the confidence interval of -0.05251195 to -0.02031007 is below zero, it agrees with the p-value: the estimated mean log duration is lower for the day than the night. It dose not cross the zero, so zero difference isn’t supported at the 95% confidence level.

Conclusion

The Null hypothesis of equal mean log-transformed duration is rejected; however, the results do not indicate a large practical difference in sighting duration between the Day and Night periods. A Welch two-sample t-test was used to compare log10-transformed sighting durations between the Day (06:00–17:59) and Night (18:00–05:59) groups. The test found a statistically significant difference between the groups, t = -4.43, p < 0.001. The mean log10 duration was 2.121 for Day sightings and 2.157 for Night sightings. Although the difference was statistically significant, its magnitude was small. The median duration was 3 minutes and the IQR was 9.5 minutes for both groups, indicating that the typical durations and spread of the middle 50% were very similar. Therefore, the large sample size allowed the test to detect a small difference that may have little practical significance.