Health Care Data Analysis with Apple Watch


Jihong Zhang


July 6, 2021

The data contained within Health app on iPhone can be saved and exported for other uses. Perhaps you want to export Health app data to use in another health or fitness app, importing it to elsewhere, or maybe you want to use the raw Health data for your own purposes.

Exporting Health data from iPhone results in a zip archive that contains the raw data as gathered by Health app in XML format. This exported Health data will include any data stored or gathered by the Health app and any associated devices, including any Medical ID data, the native iPhone step counter and distance tracker, any data from an Apple Watch, and any data gathered from any third party devices that are syncing to Health app, like a smart scale or blood pressure monitor.

You can find more details about exporting data from How to Export Health Data form iPhone and How to Export, Parse and Explore Your Apple Health Data with Python.

1 Load Required Packages

rm(list = ls(all = TRUE))

if(!require(XML)) install.packages("XML")
if(!require(tidyverse)) install.packages("tidyverse")
Warning: package 'dplyr' was built under R version 4.2.3
Warning: package 'stringr' was built under R version 4.2.3
Warning: package 'scales' was built under R version 4.2.3
if(!require(ggthemes)) remotes::install_github(c("hadley/ggplot2", "jrnold/ggthemes"))
if(!require(ggridges)) remotes::install_github("wilkelab/ggridges")
if(!require(rpart)) install.packages("rpart")
if(!require(kableExtra)) install.packages("kableExtra")

2 Read in XML data

The .xml file could be downloaded and exported directly from iphone’s health app. To read in the XML file and transform it into data frame, XML R package will help.

loc<-"导出.xml" # enter file path location of export.xml file here #

xml <- xmlParse(loc)

rc <-  data.frame(XML:::xmlAttrsToDataFrame(xml["//Record"]), stringsAsFactors = F)
saveRDS(rc, "export_health_care.rds")
rc <- readRDS("export_health_care.rds")

## Filter useful data
apple_watch <- rc %>% filter(grepl("JZ",sourceName), unit == 'count/min', 
                             type == "HKQuantityTypeIdentifierRestingHeartRate")

# Adjusting to Local Timezone
apple_watch_dt <- apple_watch %>%
  mutate(cdt=as_datetime(creationDate, tz="US/Central"),
         stm=as_datetime(startDate, tz="US/Central"),
         etm=as_datetime(endDate, tz="US/Central"),

# %>%
#   group_by(creationDate) %>%
#   mutate(TotalTime=cumsum(value)) %>% # cumulative distance covered #
#   mutate(hr=hour(stm), min=minute(stm)) %>%
#   mutate(elt=as.numeric(etm-mntm)) %>% # total elapsed time #
#   mutate(dtm=as.numeric(etm-lag(etm))) %>%
#   ungroup()
head(apple_watch_dt[,-1]) %>% 
  select(sourceName, unit, cdt, stm, etm, dst) %>% 
  kbl() %>% 
  kable_material_dark(full_width = F, html_font = "Maven Pro") |> 
  kable_styling(font_size = 10)
sourceName unit cdt stm etm dst
JZ’sApple Watch count/min 2020-07-27 22:42:32 2020-07-27 08:45:05 2020-07-27 22:37:26 60
JZ’sApple Watch count/min 2020-07-28 19:43:28 2020-07-28 00:03:04 2020-07-28 19:40:28 59
JZ’sApple Watch count/min 2020-07-29 14:22:15 2020-07-29 08:40:16 2020-07-29 14:18:28 54
JZ’sApple Watch count/min 2020-07-30 17:44:05 2020-07-30 09:06:24 2020-07-30 17:41:27 54
JZ’sApple Watch count/min 2020-07-31 17:36:00 2020-07-31 08:55:46 2020-07-31 17:27:30 52
JZ’sApple Watch count/min 2020-08-01 12:17:02 2020-08-01 00:03:31 2020-08-01 12:14:41 60

3 Other materials

There a decent blog illustrating how to handle with apple watch export file.

Back to top