boB Rudis
3 years ago
16 changed files with 160 additions and 15 deletions
@ -0,0 +1,2 @@ |
|||||
|
YEAR: 2021 |
||||
|
COPYRIGHT HOLDER: Bob Rudis |
@ -0,0 +1,21 @@ |
|||||
|
# MIT License |
||||
|
|
||||
|
Copyright (c) 2021 Bob Rudis |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in all |
||||
|
copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
|
SOFTWARE. |
@ -1,4 +1,4 @@ |
|||||
# Generated by roxygen2: do not edit by hand |
# Generated by roxygen2: do not edit by hand |
||||
|
|
||||
import(httr) |
export(parts_of_speech) |
||||
importFrom(jsonlite,fromJSON) |
useDynLib(swiftspeech, .registration = TRUE) |
||||
|
@ -0,0 +1,13 @@ |
|||||
|
#' Parts of speech |
||||
|
#' |
||||
|
#' @usage |
||||
|
#' parts_of_speech("The ripe taste of cheese improves with age.") |
||||
|
#' @param x words |
||||
|
#' @return (list) one vector with words, one with parts of speech |
||||
|
#' @export |
||||
|
#' @examples |
||||
|
#' parts_of_speech("The ripe taste of cheese improves with age.") |
||||
|
parts_of_speech <- function(x) { |
||||
|
res <- .Call("part_of_speech", x) |
||||
|
as.data.frame(stats::setNames(res, c("name", "tag"))) |
||||
|
} |
@ -1,9 +1,8 @@ |
|||||
#' ... |
#' Classify Parts of Speech Using Apple's CoreML and NaturalLanguage Libraries |
||||
#' |
#' |
||||
#' @md |
#' @md |
||||
#' @name swiftspeech |
#' @name swiftspeech |
||||
#' @keywords internal |
#' @keywords internal |
||||
#' @author Bob Rudis (bob@@rud.is) |
#' @author Bob Rudis (bob@@rud.is) |
||||
#' @import httr |
#' @useDynLib swiftspeech, .registration = TRUE |
||||
#' @importFrom jsonlite fromJSON |
|
||||
"_PACKAGE" |
"_PACKAGE" |
||||
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,20 @@ |
|||||
|
% Generated by roxygen2: do not edit by hand |
||||
|
% Please edit documentation in R/parts-of-speech.R |
||||
|
\name{parts_of_speech} |
||||
|
\alias{parts_of_speech} |
||||
|
\title{Parts of speech} |
||||
|
\usage{ |
||||
|
parts_of_speech("The ripe taste of cheese improves with age.") |
||||
|
} |
||||
|
\arguments{ |
||||
|
\item{x}{words} |
||||
|
} |
||||
|
\value{ |
||||
|
(list) one vector with words, one with parts of speech |
||||
|
} |
||||
|
\description{ |
||||
|
Parts of speech |
||||
|
} |
||||
|
\examples{ |
||||
|
parts_of_speech("The ripe taste of cheese improves with age.") |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
SWIFTC = /usr/bin/swiftc |
||||
|
INSTALL_NAME_TOOL = /usr/bin/install_name_tool |
||||
|
SWIFTLIB = libswiftspeech.dylib |
||||
|
LIBDIR = ../inst/lib |
||||
|
DEVLIB = ../lib |
||||
|
PKG_LIBS = -lswiftspeech -L../inst/lib |
||||
|
|
||||
|
all: $(SHLIB) swiftLibrary |
||||
|
|
||||
|
swiftLibrary: $(SWIFTLIB) |
||||
|
-@if test ! -e $(LIBDIR); then mkdir -p $(LIBDIR); fi |
||||
|
-@if test ! -e $(DEVLIB); then mkdir -p $(DEVLIB); fi |
||||
|
cp $(SWIFTLIB) $(LIBDIR) |
||||
|
cp $(SWIFTLIB) $(DEVLIB) |
||||
|
|
||||
|
$(SWIFTLIB): $(OBJECTS) |
||||
|
$(SHLIB_CXXLD) -o $(SWIFTLIB) $^ $(SHLIB_CXXLDFLAGS) $(LDFLAGS) $(ALL_LIBS) |
||||
|
$(SWIFTC) -I /Library/Frameworks/R.framework/Headers -F/Library/Frameworks -framework R -framework CoreML -framework NaturalLanguage -import-objc-header swiftspeech.h -emit-library swiftspeech.swift |
||||
|
$(INSTALL_NAME_TOOL) -change $(SWIFTLIB) @loader_path/../lib/$(SWIFTLIB) swiftspeech.so |
||||
|
|
||||
|
clean: |
||||
|
rm -Rf $(SHLIB) $(SWIFTLIB) $(OBJECTS) $(DEVLIB)/$(SWIFTLIB) |
@ -0,0 +1,21 @@ |
|||||
|
#include <R.h> |
||||
|
#include <Rinternals.h> |
||||
|
#include <stdlib.h> // for NULL |
||||
|
#include <R_ext/Rdynload.h> |
||||
|
|
||||
|
/* .Call calls */ |
||||
|
extern SEXP hey(); |
||||
|
extern SEXP plus_one(SEXP); |
||||
|
extern SEXP part_of_speech(SEXP); |
||||
|
|
||||
|
static const R_CallMethodDef CallEntries[] = { |
||||
|
{"hey", (DL_FUNC) &hey, 0}, |
||||
|
{"plus_one", (DL_FUNC) &plus_one, 1}, |
||||
|
{"part_of_speech", (DL_FUNC) &part_of_speech, 1}, |
||||
|
{NULL, NULL, 0} |
||||
|
}; |
||||
|
|
||||
|
void R_init_daybreak(DllInfo *dll) { |
||||
|
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); |
||||
|
R_useDynamicSymbols(dll, FALSE); |
||||
|
} |
Binary file not shown.
@ -0,0 +1,6 @@ |
|||||
|
#define USE_RINTERNALS |
||||
|
|
||||
|
#include <R.h> |
||||
|
#include <Rinternals.h> |
||||
|
|
||||
|
const char* R_CHAR(SEXP x); |
@ -0,0 +1,40 @@ |
|||||
|
import NaturalLanguage |
||||
|
import CoreML |
||||
|
|
||||
|
extension Array where Element == String { |
||||
|
var SEXP: SEXP? { |
||||
|
let charVec = Rf_protect(Rf_allocVector(SEXPTYPE(STRSXP), count)) |
||||
|
defer { Rf_unprotect(1) } |
||||
|
for (idx, elem) in enumerated() { SET_STRING_ELT(charVec, idx, Rf_mkChar(elem)) } |
||||
|
return(charVec) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@_cdecl("part_of_speech") |
||||
|
public func part_of_speech(_ x: SEXP) -> SEXP { |
||||
|
|
||||
|
let text = String(cString: R_CHAR(STRING_ELT(x, 0))) |
||||
|
let tagger = NLTagger(tagSchemes: [.lexicalClass]) |
||||
|
|
||||
|
tagger.string = text |
||||
|
|
||||
|
let options: NLTagger.Options = [.omitPunctuation, .omitWhitespace] |
||||
|
|
||||
|
var txts = [String]() |
||||
|
var tags = [String]() |
||||
|
|
||||
|
tagger.enumerateTags(in: text.startIndex..<text.endIndex, unit: .word, scheme: .lexicalClass, options: options) { tag, tokenRange in |
||||
|
if let tag = tag { |
||||
|
txts.append("\(text[tokenRange])") |
||||
|
tags.append("\(tag.rawValue)") |
||||
|
} |
||||
|
return true |
||||
|
} |
||||
|
|
||||
|
let out = Rf_protect(Rf_allocVector(SEXPTYPE(VECSXP), 2)) |
||||
|
SET_VECTOR_ELT(out, 0, txts.SEXP) |
||||
|
SET_VECTOR_ELT(out, 1, tags.SEXP) |
||||
|
Rf_unprotect(1) |
||||
|
|
||||
|
return(out!) |
||||
|
} |
Loading…
Reference in new issue