Skip to content

ARROW-4560: [R] array() needs to take single input, not ... - #3635

Closed
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots
Closed

ARROW-4560: [R] array() needs to take single input, not ...#3635
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots

Conversation

@romainfrancois

Copy link
Copy Markdown
Contributor

This will simplify the handling of the type argument.

jira: https://issues.apache.org/jira/browse/ARROW-4560?filter=12344983

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

Also planning to work on https://issues.apache.org/jira/browse/ARROW-3810 in this PR

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

To handle the type= argument in array() we need to be able to infer arrow types from R objects, so I've added the type() function:

library(arrow, warn.conflicts=FALSE)
type(1:10)
#> arrow::Int32 #> int32
type(1)
#> arrow::Float64 #> double
type("")
#> arrow::Utf8 #> string
type(iris$Species)
#> arrow::DictionaryType #> dictionary<values=string, indices=int8, ordered=0>

Created on 2019-02-14 by the reprex package (v0.2.1.9000)

@romainfrancois
romainfrancoisforce-pushed the ARROW-4560/array_no_dots branch 2 times, most recently from 0829631 to 916f76aCompareFebruary 19, 2019 15:39
@romainfrancoisromainfrancois added ready-for-review and removed WIP PR is work in progress labels Feb 20, 2019
@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

I'm now fairly confident about this PR. array() used to take ... and rely on vctrs to first combine to a common type using vctrs type system, though the .ptype. I've changed that so that array() only take one vector x and the type= argument is an arrow logical type, e.g. int32().

library(arrow, warn.conflicts=FALSE)
a<-array(1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 6 7 8 9 10a<-array(1:10, type= float64())
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1 2 3 4 5 6 7 8 9 10

The type of array that is made is governed by the type= argument. If missing, the type is inferred from the data, e.g.

library(arrow, warn.conflicts=FALSE)
a<-array(rnorm(10))
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 0.48428301 0.74399694 0.48991163 0.35701469 0.60517996#> [6] 0.53463545 0.12579375 0.02414986 -0.49127583 0.17194012

The chunked_array() factory handles ... and a type argument too:

library(arrow, warn.conflicts=FALSE)
a<- chunked_array(rnorm(10), 1:10)
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1.64642028 -1.47423016 0.84996187 1.21151724 -1.52303727#> [6] -0.04387242 -0.47798708 -0.18693768 -0.98903429 0.30376938#> [11] 1.00000000 2.00000000 3.00000000 4.00000000 5.00000000#> [16] 6.00000000 7.00000000 8.00000000 9.00000000 10.00000000a<- chunked_array(1:5, 1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 1 2 3 4 5 6 7 8 9 10

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, this looks nice. I'm going to rebase to fix any linting issue since I just added the cpplint checks


test_that("type() infers from R type", {
expect_equal(type(1:10), int32())
expect_equal(type(1), float64())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optics of this are a bit odd =)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah maybe that can be infer_type() or something

Comment threadr/tests/testthat/test-type.R
expect_equal(type(""), utf8())
expect_equal(
type(iris$Species),
dictionary(int8(), array(levels(iris$Species)), FALSE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe test for ordered factors at some point also?

@wesmwesm closed this in 2a14c7bFeb 27, 2019
@wesm

wesm commented Feb 27, 2019

Copy link
Copy Markdown
Member

Oops I missed array_from_vector.cpp in my code review because it was hidden. silly GitHub. I'll take a skim through anyway

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments. I'll do a better job reviewing next time...

null_bitmap_writer.Finish();
}

// ----- data buffer

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is efficient to visit the string elements twice? I think you should have some benchmarks about this

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so we only AllocateBuffer the buffer with the final size we need. The LENGTH() here is quick, R strings know their size: https://purrple.cat/blog/2018/03/05/strings-know-their-own-length/

Is the alternative to grow a buffer as we go ? Maybe there is a StringArrayBuilder I can use

// catch up
for (R_xlen_t j = 0; j < i; j++, null_bitmap_writer.Next()) {
null_bitmap_writer.Set();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like you might want to turn some of this into helper functions

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. We can revisit next time on this.

} else {
null_bitmap_writer.Set();
*p_indices = *p_factor - 1;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to write this without a branch


virtual Status GetResult(std::shared_ptr<arrow::Array>* result) {
RETURN_NOT_OK(builder_->Finish(result));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can return builder_->Finish(result)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Will do in a next PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@romainfrancois@wesm
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
ARROW-4560: [R] array() needs to take single input, not ... by romainfrancois · Pull Request #3635 · apache/arrow · GitHub
Skip to content

ARROW-4560: [R] array() needs to take single input, not ... - #3635

Closed
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots
Closed

ARROW-4560: [R] array() needs to take single input, not ...#3635
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots

Conversation

@romainfrancois

Copy link
Copy Markdown
Contributor

This will simplify the handling of the type argument.

jira: https://issues.apache.org/jira/browse/ARROW-4560?filter=12344983

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

Also planning to work on https://issues.apache.org/jira/browse/ARROW-3810 in this PR

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

To handle the type= argument in array() we need to be able to infer arrow types from R objects, so I've added the type() function:

library(arrow, warn.conflicts=FALSE)
type(1:10)
#> arrow::Int32 #> int32
type(1)
#> arrow::Float64 #> double
type("")
#> arrow::Utf8 #> string
type(iris$Species)
#> arrow::DictionaryType #> dictionary<values=string, indices=int8, ordered=0>

Created on 2019-02-14 by the reprex package (v0.2.1.9000)

@romainfrancois
romainfrancoisforce-pushed the ARROW-4560/array_no_dots branch 2 times, most recently from 0829631 to 916f76aCompareFebruary 19, 2019 15:39
@romainfrancoisromainfrancois added ready-for-review and removed WIP PR is work in progress labels Feb 20, 2019
@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

I'm now fairly confident about this PR. array() used to take ... and rely on vctrs to first combine to a common type using vctrs type system, though the .ptype. I've changed that so that array() only take one vector x and the type= argument is an arrow logical type, e.g. int32().

library(arrow, warn.conflicts=FALSE)
a<-array(1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 6 7 8 9 10a<-array(1:10, type= float64())
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1 2 3 4 5 6 7 8 9 10

The type of array that is made is governed by the type= argument. If missing, the type is inferred from the data, e.g.

library(arrow, warn.conflicts=FALSE)
a<-array(rnorm(10))
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 0.48428301 0.74399694 0.48991163 0.35701469 0.60517996#> [6] 0.53463545 0.12579375 0.02414986 -0.49127583 0.17194012

The chunked_array() factory handles ... and a type argument too:

library(arrow, warn.conflicts=FALSE)
a<- chunked_array(rnorm(10), 1:10)
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1.64642028 -1.47423016 0.84996187 1.21151724 -1.52303727#> [6] -0.04387242 -0.47798708 -0.18693768 -0.98903429 0.30376938#> [11] 1.00000000 2.00000000 3.00000000 4.00000000 5.00000000#> [16] 6.00000000 7.00000000 8.00000000 9.00000000 10.00000000a<- chunked_array(1:5, 1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 1 2 3 4 5 6 7 8 9 10

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, this looks nice. I'm going to rebase to fix any linting issue since I just added the cpplint checks


test_that("type() infers from R type", {
expect_equal(type(1:10), int32())
expect_equal(type(1), float64())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optics of this are a bit odd =)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah maybe that can be infer_type() or something

Comment threadr/tests/testthat/test-type.R
expect_equal(type(""), utf8())
expect_equal(
type(iris$Species),
dictionary(int8(), array(levels(iris$Species)), FALSE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe test for ordered factors at some point also?

@wesmwesm closed this in 2a14c7bFeb 27, 2019
@wesm

wesm commented Feb 27, 2019

Copy link
Copy Markdown
Member

Oops I missed array_from_vector.cpp in my code review because it was hidden. silly GitHub. I'll take a skim through anyway

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments. I'll do a better job reviewing next time...

null_bitmap_writer.Finish();
}

// ----- data buffer

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is efficient to visit the string elements twice? I think you should have some benchmarks about this

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so we only AllocateBuffer the buffer with the final size we need. The LENGTH() here is quick, R strings know their size: https://purrple.cat/blog/2018/03/05/strings-know-their-own-length/

Is the alternative to grow a buffer as we go ? Maybe there is a StringArrayBuilder I can use

// catch up
for (R_xlen_t j = 0; j < i; j++, null_bitmap_writer.Next()) {
null_bitmap_writer.Set();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like you might want to turn some of this into helper functions

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. We can revisit next time on this.

} else {
null_bitmap_writer.Set();
*p_indices = *p_factor - 1;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to write this without a branch


virtual Status GetResult(std::shared_ptr<arrow::Array>* result) {
RETURN_NOT_OK(builder_->Finish(result));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can return builder_->Finish(result)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Will do in a next PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@romainfrancois@wesm
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' ARROW-4560: [R] array() needs to take single input, not ... by romainfrancois · Pull Request #3635 · apache/arrow · GitHub
Skip to content

ARROW-4560: [R] array() needs to take single input, not ... - #3635

Closed
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots
Closed

ARROW-4560: [R] array() needs to take single input, not ...#3635
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots

Conversation

@romainfrancois

Copy link
Copy Markdown
Contributor

This will simplify the handling of the type argument.

jira: https://issues.apache.org/jira/browse/ARROW-4560?filter=12344983

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

Also planning to work on https://issues.apache.org/jira/browse/ARROW-3810 in this PR

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

To handle the type= argument in array() we need to be able to infer arrow types from R objects, so I've added the type() function:

library(arrow, warn.conflicts=FALSE)
type(1:10)
#> arrow::Int32 #> int32
type(1)
#> arrow::Float64 #> double
type("")
#> arrow::Utf8 #> string
type(iris$Species)
#> arrow::DictionaryType #> dictionary<values=string, indices=int8, ordered=0>

Created on 2019-02-14 by the reprex package (v0.2.1.9000)

@romainfrancois
romainfrancoisforce-pushed the ARROW-4560/array_no_dots branch 2 times, most recently from 0829631 to 916f76aCompareFebruary 19, 2019 15:39
@romainfrancoisromainfrancois added ready-for-review and removed WIP PR is work in progress labels Feb 20, 2019
@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

I'm now fairly confident about this PR. array() used to take ... and rely on vctrs to first combine to a common type using vctrs type system, though the .ptype. I've changed that so that array() only take one vector x and the type= argument is an arrow logical type, e.g. int32().

library(arrow, warn.conflicts=FALSE)
a<-array(1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 6 7 8 9 10a<-array(1:10, type= float64())
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1 2 3 4 5 6 7 8 9 10

The type of array that is made is governed by the type= argument. If missing, the type is inferred from the data, e.g.

library(arrow, warn.conflicts=FALSE)
a<-array(rnorm(10))
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 0.48428301 0.74399694 0.48991163 0.35701469 0.60517996#> [6] 0.53463545 0.12579375 0.02414986 -0.49127583 0.17194012

The chunked_array() factory handles ... and a type argument too:

library(arrow, warn.conflicts=FALSE)
a<- chunked_array(rnorm(10), 1:10)
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1.64642028 -1.47423016 0.84996187 1.21151724 -1.52303727#> [6] -0.04387242 -0.47798708 -0.18693768 -0.98903429 0.30376938#> [11] 1.00000000 2.00000000 3.00000000 4.00000000 5.00000000#> [16] 6.00000000 7.00000000 8.00000000 9.00000000 10.00000000a<- chunked_array(1:5, 1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 1 2 3 4 5 6 7 8 9 10

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, this looks nice. I'm going to rebase to fix any linting issue since I just added the cpplint checks


test_that("type() infers from R type", {
expect_equal(type(1:10), int32())
expect_equal(type(1), float64())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optics of this are a bit odd =)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah maybe that can be infer_type() or something

Comment threadr/tests/testthat/test-type.R
expect_equal(type(""), utf8())
expect_equal(
type(iris$Species),
dictionary(int8(), array(levels(iris$Species)), FALSE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe test for ordered factors at some point also?

@wesmwesm closed this in 2a14c7bFeb 27, 2019
@wesm

wesm commented Feb 27, 2019

Copy link
Copy Markdown
Member

Oops I missed array_from_vector.cpp in my code review because it was hidden. silly GitHub. I'll take a skim through anyway

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments. I'll do a better job reviewing next time...

null_bitmap_writer.Finish();
}

// ----- data buffer

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is efficient to visit the string elements twice? I think you should have some benchmarks about this

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so we only AllocateBuffer the buffer with the final size we need. The LENGTH() here is quick, R strings know their size: https://purrple.cat/blog/2018/03/05/strings-know-their-own-length/

Is the alternative to grow a buffer as we go ? Maybe there is a StringArrayBuilder I can use

// catch up
for (R_xlen_t j = 0; j < i; j++, null_bitmap_writer.Next()) {
null_bitmap_writer.Set();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like you might want to turn some of this into helper functions

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. We can revisit next time on this.

} else {
null_bitmap_writer.Set();
*p_indices = *p_factor - 1;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to write this without a branch


virtual Status GetResult(std::shared_ptr<arrow::Array>* result) {
RETURN_NOT_OK(builder_->Finish(result));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can return builder_->Finish(result)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Will do in a next PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@romainfrancois@wesm
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' ARROW-4560: [R] array() needs to take single input, not ... by romainfrancois · Pull Request #3635 · apache/arrow · GitHub
Skip to content

ARROW-4560: [R] array() needs to take single input, not ... - #3635

Closed
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots
Closed

ARROW-4560: [R] array() needs to take single input, not ...#3635
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots

Conversation

@romainfrancois

Copy link
Copy Markdown
Contributor

This will simplify the handling of the type argument.

jira: https://issues.apache.org/jira/browse/ARROW-4560?filter=12344983

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

Also planning to work on https://issues.apache.org/jira/browse/ARROW-3810 in this PR

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

To handle the type= argument in array() we need to be able to infer arrow types from R objects, so I've added the type() function:

library(arrow, warn.conflicts=FALSE)
type(1:10)
#> arrow::Int32 #> int32
type(1)
#> arrow::Float64 #> double
type("")
#> arrow::Utf8 #> string
type(iris$Species)
#> arrow::DictionaryType #> dictionary<values=string, indices=int8, ordered=0>

Created on 2019-02-14 by the reprex package (v0.2.1.9000)

@romainfrancois
romainfrancoisforce-pushed the ARROW-4560/array_no_dots branch 2 times, most recently from 0829631 to 916f76aCompareFebruary 19, 2019 15:39
@romainfrancoisromainfrancois added ready-for-review and removed WIP PR is work in progress labels Feb 20, 2019
@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

I'm now fairly confident about this PR. array() used to take ... and rely on vctrs to first combine to a common type using vctrs type system, though the .ptype. I've changed that so that array() only take one vector x and the type= argument is an arrow logical type, e.g. int32().

library(arrow, warn.conflicts=FALSE)
a<-array(1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 6 7 8 9 10a<-array(1:10, type= float64())
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1 2 3 4 5 6 7 8 9 10

The type of array that is made is governed by the type= argument. If missing, the type is inferred from the data, e.g.

library(arrow, warn.conflicts=FALSE)
a<-array(rnorm(10))
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 0.48428301 0.74399694 0.48991163 0.35701469 0.60517996#> [6] 0.53463545 0.12579375 0.02414986 -0.49127583 0.17194012

The chunked_array() factory handles ... and a type argument too:

library(arrow, warn.conflicts=FALSE)
a<- chunked_array(rnorm(10), 1:10)
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1.64642028 -1.47423016 0.84996187 1.21151724 -1.52303727#> [6] -0.04387242 -0.47798708 -0.18693768 -0.98903429 0.30376938#> [11] 1.00000000 2.00000000 3.00000000 4.00000000 5.00000000#> [16] 6.00000000 7.00000000 8.00000000 9.00000000 10.00000000a<- chunked_array(1:5, 1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 1 2 3 4 5 6 7 8 9 10

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, this looks nice. I'm going to rebase to fix any linting issue since I just added the cpplint checks


test_that("type() infers from R type", {
expect_equal(type(1:10), int32())
expect_equal(type(1), float64())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optics of this are a bit odd =)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah maybe that can be infer_type() or something

Comment threadr/tests/testthat/test-type.R
expect_equal(type(""), utf8())
expect_equal(
type(iris$Species),
dictionary(int8(), array(levels(iris$Species)), FALSE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe test for ordered factors at some point also?

@wesmwesm closed this in 2a14c7bFeb 27, 2019
@wesm

wesm commented Feb 27, 2019

Copy link
Copy Markdown
Member

Oops I missed array_from_vector.cpp in my code review because it was hidden. silly GitHub. I'll take a skim through anyway

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments. I'll do a better job reviewing next time...

null_bitmap_writer.Finish();
}

// ----- data buffer

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is efficient to visit the string elements twice? I think you should have some benchmarks about this

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so we only AllocateBuffer the buffer with the final size we need. The LENGTH() here is quick, R strings know their size: https://purrple.cat/blog/2018/03/05/strings-know-their-own-length/

Is the alternative to grow a buffer as we go ? Maybe there is a StringArrayBuilder I can use

// catch up
for (R_xlen_t j = 0; j < i; j++, null_bitmap_writer.Next()) {
null_bitmap_writer.Set();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like you might want to turn some of this into helper functions

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. We can revisit next time on this.

} else {
null_bitmap_writer.Set();
*p_indices = *p_factor - 1;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to write this without a branch


virtual Status GetResult(std::shared_ptr<arrow::Array>* result) {
RETURN_NOT_OK(builder_->Finish(result));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can return builder_->Finish(result)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Will do in a next PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@romainfrancois@wesm
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' ARROW-4560: [R] array() needs to take single input, not ... by romainfrancois · Pull Request #3635 · apache/arrow · GitHub
Skip to content

ARROW-4560: [R] array() needs to take single input, not ... - #3635

Closed
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots
Closed

ARROW-4560: [R] array() needs to take single input, not ...#3635
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots

Conversation

@romainfrancois

Copy link
Copy Markdown
Contributor

This will simplify the handling of the type argument.

jira: https://issues.apache.org/jira/browse/ARROW-4560?filter=12344983

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

Also planning to work on https://issues.apache.org/jira/browse/ARROW-3810 in this PR

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

To handle the type= argument in array() we need to be able to infer arrow types from R objects, so I've added the type() function:

library(arrow, warn.conflicts=FALSE)
type(1:10)
#> arrow::Int32 #> int32
type(1)
#> arrow::Float64 #> double
type("")
#> arrow::Utf8 #> string
type(iris$Species)
#> arrow::DictionaryType #> dictionary<values=string, indices=int8, ordered=0>

Created on 2019-02-14 by the reprex package (v0.2.1.9000)

@romainfrancois
romainfrancoisforce-pushed the ARROW-4560/array_no_dots branch 2 times, most recently from 0829631 to 916f76aCompareFebruary 19, 2019 15:39
@romainfrancoisromainfrancois added ready-for-review and removed WIP PR is work in progress labels Feb 20, 2019
@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

I'm now fairly confident about this PR. array() used to take ... and rely on vctrs to first combine to a common type using vctrs type system, though the .ptype. I've changed that so that array() only take one vector x and the type= argument is an arrow logical type, e.g. int32().

library(arrow, warn.conflicts=FALSE)
a<-array(1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 6 7 8 9 10a<-array(1:10, type= float64())
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1 2 3 4 5 6 7 8 9 10

The type of array that is made is governed by the type= argument. If missing, the type is inferred from the data, e.g.

library(arrow, warn.conflicts=FALSE)
a<-array(rnorm(10))
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 0.48428301 0.74399694 0.48991163 0.35701469 0.60517996#> [6] 0.53463545 0.12579375 0.02414986 -0.49127583 0.17194012

The chunked_array() factory handles ... and a type argument too:

library(arrow, warn.conflicts=FALSE)
a<- chunked_array(rnorm(10), 1:10)
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1.64642028 -1.47423016 0.84996187 1.21151724 -1.52303727#> [6] -0.04387242 -0.47798708 -0.18693768 -0.98903429 0.30376938#> [11] 1.00000000 2.00000000 3.00000000 4.00000000 5.00000000#> [16] 6.00000000 7.00000000 8.00000000 9.00000000 10.00000000a<- chunked_array(1:5, 1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 1 2 3 4 5 6 7 8 9 10

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, this looks nice. I'm going to rebase to fix any linting issue since I just added the cpplint checks


test_that("type() infers from R type", {
expect_equal(type(1:10), int32())
expect_equal(type(1), float64())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optics of this are a bit odd =)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah maybe that can be infer_type() or something

Comment threadr/tests/testthat/test-type.R
expect_equal(type(""), utf8())
expect_equal(
type(iris$Species),
dictionary(int8(), array(levels(iris$Species)), FALSE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe test for ordered factors at some point also?

@wesmwesm closed this in 2a14c7bFeb 27, 2019
@wesm

wesm commented Feb 27, 2019

Copy link
Copy Markdown
Member

Oops I missed array_from_vector.cpp in my code review because it was hidden. silly GitHub. I'll take a skim through anyway

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments. I'll do a better job reviewing next time...

null_bitmap_writer.Finish();
}

// ----- data buffer

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is efficient to visit the string elements twice? I think you should have some benchmarks about this

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so we only AllocateBuffer the buffer with the final size we need. The LENGTH() here is quick, R strings know their size: https://purrple.cat/blog/2018/03/05/strings-know-their-own-length/

Is the alternative to grow a buffer as we go ? Maybe there is a StringArrayBuilder I can use

// catch up
for (R_xlen_t j = 0; j < i; j++, null_bitmap_writer.Next()) {
null_bitmap_writer.Set();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like you might want to turn some of this into helper functions

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. We can revisit next time on this.

} else {
null_bitmap_writer.Set();
*p_indices = *p_factor - 1;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to write this without a branch


virtual Status GetResult(std::shared_ptr<arrow::Array>* result) {
RETURN_NOT_OK(builder_->Finish(result));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can return builder_->Finish(result)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Will do in a next PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@romainfrancois@wesm
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' ARROW-4560: [R] array() needs to take single input, not ... by romainfrancois · Pull Request #3635 · apache/arrow · GitHub
Skip to content

ARROW-4560: [R] array() needs to take single input, not ... - #3635

Closed
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots
Closed

ARROW-4560: [R] array() needs to take single input, not ...#3635
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots

Conversation

@romainfrancois

Copy link
Copy Markdown
Contributor

This will simplify the handling of the type argument.

jira: https://issues.apache.org/jira/browse/ARROW-4560?filter=12344983

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

Also planning to work on https://issues.apache.org/jira/browse/ARROW-3810 in this PR

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

To handle the type= argument in array() we need to be able to infer arrow types from R objects, so I've added the type() function:

library(arrow, warn.conflicts=FALSE)
type(1:10)
#> arrow::Int32 #> int32
type(1)
#> arrow::Float64 #> double
type("")
#> arrow::Utf8 #> string
type(iris$Species)
#> arrow::DictionaryType #> dictionary<values=string, indices=int8, ordered=0>

Created on 2019-02-14 by the reprex package (v0.2.1.9000)

@romainfrancois
romainfrancoisforce-pushed the ARROW-4560/array_no_dots branch 2 times, most recently from 0829631 to 916f76aCompareFebruary 19, 2019 15:39
@romainfrancoisromainfrancois added ready-for-review and removed WIP PR is work in progress labels Feb 20, 2019
@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

I'm now fairly confident about this PR. array() used to take ... and rely on vctrs to first combine to a common type using vctrs type system, though the .ptype. I've changed that so that array() only take one vector x and the type= argument is an arrow logical type, e.g. int32().

library(arrow, warn.conflicts=FALSE)
a<-array(1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 6 7 8 9 10a<-array(1:10, type= float64())
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1 2 3 4 5 6 7 8 9 10

The type of array that is made is governed by the type= argument. If missing, the type is inferred from the data, e.g.

library(arrow, warn.conflicts=FALSE)
a<-array(rnorm(10))
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 0.48428301 0.74399694 0.48991163 0.35701469 0.60517996#> [6] 0.53463545 0.12579375 0.02414986 -0.49127583 0.17194012

The chunked_array() factory handles ... and a type argument too:

library(arrow, warn.conflicts=FALSE)
a<- chunked_array(rnorm(10), 1:10)
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1.64642028 -1.47423016 0.84996187 1.21151724 -1.52303727#> [6] -0.04387242 -0.47798708 -0.18693768 -0.98903429 0.30376938#> [11] 1.00000000 2.00000000 3.00000000 4.00000000 5.00000000#> [16] 6.00000000 7.00000000 8.00000000 9.00000000 10.00000000a<- chunked_array(1:5, 1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 1 2 3 4 5 6 7 8 9 10

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, this looks nice. I'm going to rebase to fix any linting issue since I just added the cpplint checks


test_that("type() infers from R type", {
expect_equal(type(1:10), int32())
expect_equal(type(1), float64())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optics of this are a bit odd =)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah maybe that can be infer_type() or something

Comment threadr/tests/testthat/test-type.R
expect_equal(type(""), utf8())
expect_equal(
type(iris$Species),
dictionary(int8(), array(levels(iris$Species)), FALSE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe test for ordered factors at some point also?

@wesmwesm closed this in 2a14c7bFeb 27, 2019
@wesm

wesm commented Feb 27, 2019

Copy link
Copy Markdown
Member

Oops I missed array_from_vector.cpp in my code review because it was hidden. silly GitHub. I'll take a skim through anyway

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments. I'll do a better job reviewing next time...

null_bitmap_writer.Finish();
}

// ----- data buffer

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is efficient to visit the string elements twice? I think you should have some benchmarks about this

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so we only AllocateBuffer the buffer with the final size we need. The LENGTH() here is quick, R strings know their size: https://purrple.cat/blog/2018/03/05/strings-know-their-own-length/

Is the alternative to grow a buffer as we go ? Maybe there is a StringArrayBuilder I can use

// catch up
for (R_xlen_t j = 0; j < i; j++, null_bitmap_writer.Next()) {
null_bitmap_writer.Set();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like you might want to turn some of this into helper functions

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. We can revisit next time on this.

} else {
null_bitmap_writer.Set();
*p_indices = *p_factor - 1;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to write this without a branch


virtual Status GetResult(std::shared_ptr<arrow::Array>* result) {
RETURN_NOT_OK(builder_->Finish(result));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can return builder_->Finish(result)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Will do in a next PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@romainfrancois@wesm
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' ARROW-4560: [R] array() needs to take single input, not ... by romainfrancois · Pull Request #3635 · apache/arrow · GitHub
Skip to content

ARROW-4560: [R] array() needs to take single input, not ... - #3635

Closed
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots
Closed

ARROW-4560: [R] array() needs to take single input, not ...#3635
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots

Conversation

@romainfrancois

Copy link
Copy Markdown
Contributor

This will simplify the handling of the type argument.

jira: https://issues.apache.org/jira/browse/ARROW-4560?filter=12344983

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

Also planning to work on https://issues.apache.org/jira/browse/ARROW-3810 in this PR

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

To handle the type= argument in array() we need to be able to infer arrow types from R objects, so I've added the type() function:

library(arrow, warn.conflicts=FALSE)
type(1:10)
#> arrow::Int32 #> int32
type(1)
#> arrow::Float64 #> double
type("")
#> arrow::Utf8 #> string
type(iris$Species)
#> arrow::DictionaryType #> dictionary<values=string, indices=int8, ordered=0>

Created on 2019-02-14 by the reprex package (v0.2.1.9000)

@romainfrancois
romainfrancoisforce-pushed the ARROW-4560/array_no_dots branch 2 times, most recently from 0829631 to 916f76aCompareFebruary 19, 2019 15:39
@romainfrancoisromainfrancois added ready-for-review and removed WIP PR is work in progress labels Feb 20, 2019
@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

I'm now fairly confident about this PR. array() used to take ... and rely on vctrs to first combine to a common type using vctrs type system, though the .ptype. I've changed that so that array() only take one vector x and the type= argument is an arrow logical type, e.g. int32().

library(arrow, warn.conflicts=FALSE)
a<-array(1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 6 7 8 9 10a<-array(1:10, type= float64())
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1 2 3 4 5 6 7 8 9 10

The type of array that is made is governed by the type= argument. If missing, the type is inferred from the data, e.g.

library(arrow, warn.conflicts=FALSE)
a<-array(rnorm(10))
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 0.48428301 0.74399694 0.48991163 0.35701469 0.60517996#> [6] 0.53463545 0.12579375 0.02414986 -0.49127583 0.17194012

The chunked_array() factory handles ... and a type argument too:

library(arrow, warn.conflicts=FALSE)
a<- chunked_array(rnorm(10), 1:10)
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1.64642028 -1.47423016 0.84996187 1.21151724 -1.52303727#> [6] -0.04387242 -0.47798708 -0.18693768 -0.98903429 0.30376938#> [11] 1.00000000 2.00000000 3.00000000 4.00000000 5.00000000#> [16] 6.00000000 7.00000000 8.00000000 9.00000000 10.00000000a<- chunked_array(1:5, 1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 1 2 3 4 5 6 7 8 9 10

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, this looks nice. I'm going to rebase to fix any linting issue since I just added the cpplint checks


test_that("type() infers from R type", {
expect_equal(type(1:10), int32())
expect_equal(type(1), float64())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optics of this are a bit odd =)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah maybe that can be infer_type() or something

Comment threadr/tests/testthat/test-type.R
expect_equal(type(""), utf8())
expect_equal(
type(iris$Species),
dictionary(int8(), array(levels(iris$Species)), FALSE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe test for ordered factors at some point also?

@wesmwesm closed this in 2a14c7bFeb 27, 2019
@wesm

wesm commented Feb 27, 2019

Copy link
Copy Markdown
Member

Oops I missed array_from_vector.cpp in my code review because it was hidden. silly GitHub. I'll take a skim through anyway

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments. I'll do a better job reviewing next time...

null_bitmap_writer.Finish();
}

// ----- data buffer

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is efficient to visit the string elements twice? I think you should have some benchmarks about this

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so we only AllocateBuffer the buffer with the final size we need. The LENGTH() here is quick, R strings know their size: https://purrple.cat/blog/2018/03/05/strings-know-their-own-length/

Is the alternative to grow a buffer as we go ? Maybe there is a StringArrayBuilder I can use

// catch up
for (R_xlen_t j = 0; j < i; j++, null_bitmap_writer.Next()) {
null_bitmap_writer.Set();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like you might want to turn some of this into helper functions

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. We can revisit next time on this.

} else {
null_bitmap_writer.Set();
*p_indices = *p_factor - 1;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to write this without a branch


virtual Status GetResult(std::shared_ptr<arrow::Array>* result) {
RETURN_NOT_OK(builder_->Finish(result));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can return builder_->Finish(result)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Will do in a next PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@romainfrancois@wesm
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); ARROW-4560: [R] array() needs to take single input, not ... by romainfrancois · Pull Request #3635 · apache/arrow · GitHub
Skip to content

ARROW-4560: [R] array() needs to take single input, not ... - #3635

Closed
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots
Closed

ARROW-4560: [R] array() needs to take single input, not ...#3635
romainfrancois wants to merge 21 commits into
apache:masterfrom
romainfrancois:ARROW-4560/array_no_dots

Conversation

@romainfrancois

Copy link
Copy Markdown
Contributor

This will simplify the handling of the type argument.

jira: https://issues.apache.org/jira/browse/ARROW-4560?filter=12344983

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

Also planning to work on https://issues.apache.org/jira/browse/ARROW-3810 in this PR

@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

To handle the type= argument in array() we need to be able to infer arrow types from R objects, so I've added the type() function:

library(arrow, warn.conflicts=FALSE)
type(1:10)
#> arrow::Int32 #> int32
type(1)
#> arrow::Float64 #> double
type("")
#> arrow::Utf8 #> string
type(iris$Species)
#> arrow::DictionaryType #> dictionary<values=string, indices=int8, ordered=0>

Created on 2019-02-14 by the reprex package (v0.2.1.9000)

@romainfrancois
romainfrancoisforce-pushed the ARROW-4560/array_no_dots branch 2 times, most recently from 0829631 to 916f76aCompareFebruary 19, 2019 15:39
@romainfrancoisromainfrancois added ready-for-review and removed WIP PR is work in progress labels Feb 20, 2019
@romainfrancois

Copy link
Copy Markdown
ContributorAuthor

I'm now fairly confident about this PR. array() used to take ... and rely on vctrs to first combine to a common type using vctrs type system, though the .ptype. I've changed that so that array() only take one vector x and the type= argument is an arrow logical type, e.g. int32().

library(arrow, warn.conflicts=FALSE)
a<-array(1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 6 7 8 9 10a<-array(1:10, type= float64())
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1 2 3 4 5 6 7 8 9 10

The type of array that is made is governed by the type= argument. If missing, the type is inferred from the data, e.g.

library(arrow, warn.conflicts=FALSE)
a<-array(rnorm(10))
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 0.48428301 0.74399694 0.48991163 0.35701469 0.60517996#> [6] 0.53463545 0.12579375 0.02414986 -0.49127583 0.17194012

The chunked_array() factory handles ... and a type argument too:

library(arrow, warn.conflicts=FALSE)
a<- chunked_array(rnorm(10), 1:10)
a$type#> arrow::Float64 #> doublea$as_vector()
#> [1] 1.64642028 -1.47423016 0.84996187 1.21151724 -1.52303727#> [6] -0.04387242 -0.47798708 -0.18693768 -0.98903429 0.30376938#> [11] 1.00000000 2.00000000 3.00000000 4.00000000 5.00000000#> [16] 6.00000000 7.00000000 8.00000000 9.00000000 10.00000000a<- chunked_array(1:5, 1:10, type= int64())
a$type#> arrow::Int64 #> int64a$as_vector()
#> integer64#> [1] 1 2 3 4 5 1 2 3 4 5 6 7 8 9 10

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, this looks nice. I'm going to rebase to fix any linting issue since I just added the cpplint checks


test_that("type() infers from R type", {
expect_equal(type(1:10), int32())
expect_equal(type(1), float64())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optics of this are a bit odd =)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah maybe that can be infer_type() or something

Comment threadr/tests/testthat/test-type.R
expect_equal(type(""), utf8())
expect_equal(
type(iris$Species),
dictionary(int8(), array(levels(iris$Species)), FALSE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe test for ordered factors at some point also?

@wesmwesm closed this in 2a14c7bFeb 27, 2019
@wesm

wesm commented Feb 27, 2019

Copy link
Copy Markdown
Member

Oops I missed array_from_vector.cpp in my code review because it was hidden. silly GitHub. I'll take a skim through anyway

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments. I'll do a better job reviewing next time...

null_bitmap_writer.Finish();
}

// ----- data buffer

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is efficient to visit the string elements twice? I think you should have some benchmarks about this

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so we only AllocateBuffer the buffer with the final size we need. The LENGTH() here is quick, R strings know their size: https://purrple.cat/blog/2018/03/05/strings-know-their-own-length/

Is the alternative to grow a buffer as we go ? Maybe there is a StringArrayBuilder I can use

// catch up
for (R_xlen_t j = 0; j < i; j++, null_bitmap_writer.Next()) {
null_bitmap_writer.Set();
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like you might want to turn some of this into helper functions

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. We can revisit next time on this.

} else {
null_bitmap_writer.Set();
*p_indices = *p_factor - 1;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be able to write this without a branch


virtual Status GetResult(std::shared_ptr<arrow::Array>* result) {
RETURN_NOT_OK(builder_->Finish(result));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can return builder_->Finish(result)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Will do in a next PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@romainfrancois@wesm