TabularData framework lets you import, organize, and export a table of data. It’s great when you’re training a machine learning model but it’s a handy tool in many other scenarios as well.
General:
DevForums tag: TabularData
TabularData framework documentation
Explore and manipulate data in Swift with TabularData tech talk
For a ‘hello world’ style example, see this DevForums post
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
TabularData
RSS for tagImport, organize, and prepare a table of data to train a machine learning model.
Posts under TabularData tag
4 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hi everyone! I’m fairly new to Swift and currently working on a small iOS app in SwiftUI. The app is able to load a CSV file embedded in the Xcode project (using Bundle.main.path(forResource:)), and everything works well with that.
Now, I want to take it a step further by allowing the app to load an external CSV file located in the iPhone’s directories (like “Documents” or “Downloads”). However, I’m struggling to make it work. I tried using a DocumentPicker to select the CSV file, and I believe I’m passing the file URL correctly, but the app keeps reading only the embedded file instead of the one selected by the user.
Could anyone offer guidance on how to properly set up loading an external CSV file? I’m still learning, so any suggestions or examples would be really appreciated!
Thanks a lot in advance for the help!
Here’s the code that isn’t working as expected:
import Foundation
struct Product: Identifiable {
let id = UUID()
var codice: String
var descrizione: String
var prezzo: Double
var installazione: Double
var trasporto: Double
}
class ProductViewModel: ObservableObject {
@Published var products: [Product] = []
@Published var filteredProducts: [Product] = []
func loadCSV(from url: URL) {
products = []
do {
let data = try String(contentsOf: url)
let lines = data.components(separatedBy: "\n")
// Legge e processa ogni riga del CSV (saltando la prima riga se è l'intestazione)
for line in lines.dropFirst() {
let values = line.components(separatedBy: ";")
// Assicurati che ci siano abbastanza colonne e gestisci i valori mancanti
if values.count >= 5 {
let codice = values[0].trimmingCharacters(in: .whitespaces)
let descrizione = values[1].trimmingCharacters(in: .whitespaces)
let prezzo = parseEuropeanDouble(values[2]) ?? 0.0
let installazione = parseEuropeanDouble(values[3].isEmpty ? "0,00" : values[3]) ?? 0.0
let trasporto = parseEuropeanDouble(values[4].isEmpty ? "0,00" : values[4]) ?? 0.0
let product = Product(
codice: codice,
descrizione: descrizione,
prezzo: prezzo,
installazione: installazione,
trasporto: trasporto
)
products.append(product)
}
}
filteredProducts = products
} catch {
print("Errore nel caricamento del CSV: \(error)")
}
}
private func parseEuropeanDouble(_ value: String) -> Double? {
let formatter = NumberFormatter()
formatter.locale = Locale(identifier: "it_IT")
formatter.numberStyle = .decimal
return formatter.number(from: value)?.doubleValue
}
}
struct ContentView: View {
@StateObject var viewModel = ProductViewModel()
@State private var showFilePicker = false
var body: some View {
VStack {
Button("Carica file CSV") {
showFilePicker = true
}
.fileImporter(isPresented: $showFilePicker, allowedContentTypes: [.commaSeparatedText]) { result in
switch result {
case .success(let url):
viewModel.loadCSV(from: url)
case .failure(let error):
print("Errore nel caricamento del file: \(error.localizedDescription)")
}
}
List(viewModel.filteredProducts) { product in
VStack(alignment: .leading) {
Text("Codice: \(product.codice)")
Text("Descrizione: \(product.descrizione)")
Text("Prezzo Lordo: €\(String(format: "%.2f", product.prezzo))")
Text("Installazione: €\(String(format: "%.2f", product.installazione))")
Text("Trasporto: €\(String(format: "%.2f", product.trasporto))")
}
}
}
.padding()
}
}
Hi, I am fairly new Xcode/Swift and am trying to load a CSV File for use in my development. I have placed the CSV file in my Assets folder but when I try to create my Data Model and load the CSV file. I run into the error: No exact matches in call to initializer. Below is the code. I have attached CSV File. Any help fixing this error would be greatly appreciated. Thanks in advance for your help.
Brian
Hospital_Demographic_Data_Sample.csv
import Foundation
import CSV
struct HospitalData: Codable {
let providerNumber: String
let hospital: String
let address: String
let city: String
let state: String
let zip: String
let wageIndex: Double
let caseMix: Double
let averageCharge: Double
let discharges: Int
let totalCharges: Double
let adjTotalCharges: Double
// Add other fields as needed based on the columns in your CSV file
}
func loadHospitalData() -> [HospitalData]? {
guard let filePath = Bundle.main.path(forResource: "Hospital_Demographic_Data", ofType: "csv") else {
print("File not found")
return nil
}
do {
let csv = try CSV(url: URL(fileURLWithPath: filePath))
var hospitalDataList = [HospitalData]() // Initialize as an empty array
for row in csv.namedRows {
if let providerNumber = String(row["Provider CCN"] ?? ""), // Replace "Provider CCN" with actual column name
let hospital = String(row["Hospital Name"] ?? ""), // Replace with actual column name
let address = String(row["Street Address"] ?? ""),
let city = String(row["City"] ?? ""), // Replace with actual column name
let state = String(row["State Code"] ?? ""), // Replace with actual column name
let zip = String(row["Zip Code"] ?? ""), // Replace with actual column name
let wageIndex = Double(row["Wage Index"] ?? ""),
let caseMix = Double(row["Case Max"] ?? ""),
let averageCharge = Double(row["Base Charge"] ?? ""), // Replace with actual column name
let discharges = Int(row["Medicare Discharges"] ?? ""),
let totalCharges = Double(row["Total Charges"] ?? ""),
let adjTotalCharges = Double(row["Total Wage Normalized Charges"] ?? "") { // Replace with actual column name
let hospitalData = HospitalData(
providerNumber: providerNumber,
hospital: hospital,
address: address,
city: city,
state: state,
zip: zip,
wageIndex: wageIndex,
caseMix: caseMix,
averageCharge: averageCharge,
discharges: discharges,
totalCharges: totalCharges,
adjTotalCharges: adjTotalCharges
)
hospitalDataList.append(hospitalData)
}
}
return hospitalDataList
} catch {
print("Failed to load CSV file: \(error)")
return nil
}
}
// Usage Example
func main() {
if let hospitalData = loadHospitalData() {
for data in hospitalData {
print("Hospital: (data.hospital), City: (data.city), Average Charge: (data.averageCharge)")
}
}
}
Hi,
In Xcode 14 I was able to train linear regression models with Create ML using large CSV files (I tested on about 30000 items and 5 features):
However, in Xcode 15 (I tested on 15.0.1 and 15.1), the training continuously stays in the "Processing" state:
When using a dataset with 900 items, everything works fine.
I filed a feedback for this issue: FB13516799.
Does anybody else have this issue / can reproduce it?
I'm building up a data frame for the sole purpose of using that lovely textual grid output. I'm getting output without any issue, but I'm trying to sort out how I might apply a formatter to a specific column so that print(dataframeInstance) "just works" nicely. In my use case, I'm running a function, collecting its output - appending that into a frame, and then using TabularData to get a nice output in a unit test, so I can see the patterns within the output.
I found https://developer.apple.com/documentation/tabulardata/column/description(options:), but wasn't able to find any way to "pre-bind" that to a dataframe Column when I was creating it. (I have some double values that get a bit "excessive" in length due to the joys of floating point rounding)
Is there a way of setting a formatter on a column at creation time, or after (using a property) that could basically use the same pattern as that description method above?