Multiple, flexible logical column comparison in Data.table
I want to compare multiple columns in a data table in R, and I do not want to hardcode them. For example, see the simple example below:
###########
#Setup data
###########
set.seed(2)
fill = data.table(n=1:7)
Tp=3
for(t in 1:Tp){
set(x = fill, j = paste0('v',t), value = sample(0:10,7))
}
fill[1,paste0('v',3):=0]
fill[5,paste0('v',2):=0]
fill[5,paste0('v',3):=0]
for(t in 1:Tp){
fill[,paste0('v',t,'prm'):=get(paste0('v',t))]
}
fill[1,paste0('v',1,'prm'):=0]
fill[2,paste0('v',2,'prm'):=1]
fill[5,paste0('v',3,'prm'):=1]
fill[7,paste0('v',3,'prm'):=2]
So the data is:
> fill
n v1 v2 v3 v1prm v2prm v3prm
1: 1 2 9 0 0 9 0
2: 2 7 4 8 7 1 8
3: 3 5 10 9 5 10 9
4: 4 1 8 1 1 8 1
5: 5 6 0 0 6 0 1
6: 6 8 7 0 8 7 0
7: 7 0 0 6 0 0 2
And I want to compare numberwise each column with its 'prm', as follows:
fill[v1==v1prm & v2==v2prm & v3==v3prm]
So the output is:
> fill[v1==v1prm & v2==v2prm & v3==v3prm]
n v1 v2 v3 v1prm v2prm v3prm
1: 3 5 10 9 5 10 9
2: 4 1 8 1 1 8 1
3: 6 8 7 0 8 7 0
But I do not want to hardcode this because I might use more than 3 columns. Also, I may want to use other comparison, such as...
> fill[v1>v1prm & v2==v2prm & v3==v3prm]
n v1 v2 v3 v1prm v2prm v3prm
1: 1 2 9 0 0 9 0
r boolean data.table logic
add a comment |
I want to compare multiple columns in a data table in R, and I do not want to hardcode them. For example, see the simple example below:
###########
#Setup data
###########
set.seed(2)
fill = data.table(n=1:7)
Tp=3
for(t in 1:Tp){
set(x = fill, j = paste0('v',t), value = sample(0:10,7))
}
fill[1,paste0('v',3):=0]
fill[5,paste0('v',2):=0]
fill[5,paste0('v',3):=0]
for(t in 1:Tp){
fill[,paste0('v',t,'prm'):=get(paste0('v',t))]
}
fill[1,paste0('v',1,'prm'):=0]
fill[2,paste0('v',2,'prm'):=1]
fill[5,paste0('v',3,'prm'):=1]
fill[7,paste0('v',3,'prm'):=2]
So the data is:
> fill
n v1 v2 v3 v1prm v2prm v3prm
1: 1 2 9 0 0 9 0
2: 2 7 4 8 7 1 8
3: 3 5 10 9 5 10 9
4: 4 1 8 1 1 8 1
5: 5 6 0 0 6 0 1
6: 6 8 7 0 8 7 0
7: 7 0 0 6 0 0 2
And I want to compare numberwise each column with its 'prm', as follows:
fill[v1==v1prm & v2==v2prm & v3==v3prm]
So the output is:
> fill[v1==v1prm & v2==v2prm & v3==v3prm]
n v1 v2 v3 v1prm v2prm v3prm
1: 3 5 10 9 5 10 9
2: 4 1 8 1 1 8 1
3: 6 8 7 0 8 7 0
But I do not want to hardcode this because I might use more than 3 columns. Also, I may want to use other comparison, such as...
> fill[v1>v1prm & v2==v2prm & v3==v3prm]
n v1 v2 v3 v1prm v2prm v3prm
1: 1 2 9 0 0 9 0
r boolean data.table logic
add a comment |
I want to compare multiple columns in a data table in R, and I do not want to hardcode them. For example, see the simple example below:
###########
#Setup data
###########
set.seed(2)
fill = data.table(n=1:7)
Tp=3
for(t in 1:Tp){
set(x = fill, j = paste0('v',t), value = sample(0:10,7))
}
fill[1,paste0('v',3):=0]
fill[5,paste0('v',2):=0]
fill[5,paste0('v',3):=0]
for(t in 1:Tp){
fill[,paste0('v',t,'prm'):=get(paste0('v',t))]
}
fill[1,paste0('v',1,'prm'):=0]
fill[2,paste0('v',2,'prm'):=1]
fill[5,paste0('v',3,'prm'):=1]
fill[7,paste0('v',3,'prm'):=2]
So the data is:
> fill
n v1 v2 v3 v1prm v2prm v3prm
1: 1 2 9 0 0 9 0
2: 2 7 4 8 7 1 8
3: 3 5 10 9 5 10 9
4: 4 1 8 1 1 8 1
5: 5 6 0 0 6 0 1
6: 6 8 7 0 8 7 0
7: 7 0 0 6 0 0 2
And I want to compare numberwise each column with its 'prm', as follows:
fill[v1==v1prm & v2==v2prm & v3==v3prm]
So the output is:
> fill[v1==v1prm & v2==v2prm & v3==v3prm]
n v1 v2 v3 v1prm v2prm v3prm
1: 3 5 10 9 5 10 9
2: 4 1 8 1 1 8 1
3: 6 8 7 0 8 7 0
But I do not want to hardcode this because I might use more than 3 columns. Also, I may want to use other comparison, such as...
> fill[v1>v1prm & v2==v2prm & v3==v3prm]
n v1 v2 v3 v1prm v2prm v3prm
1: 1 2 9 0 0 9 0
r boolean data.table logic
I want to compare multiple columns in a data table in R, and I do not want to hardcode them. For example, see the simple example below:
###########
#Setup data
###########
set.seed(2)
fill = data.table(n=1:7)
Tp=3
for(t in 1:Tp){
set(x = fill, j = paste0('v',t), value = sample(0:10,7))
}
fill[1,paste0('v',3):=0]
fill[5,paste0('v',2):=0]
fill[5,paste0('v',3):=0]
for(t in 1:Tp){
fill[,paste0('v',t,'prm'):=get(paste0('v',t))]
}
fill[1,paste0('v',1,'prm'):=0]
fill[2,paste0('v',2,'prm'):=1]
fill[5,paste0('v',3,'prm'):=1]
fill[7,paste0('v',3,'prm'):=2]
So the data is:
> fill
n v1 v2 v3 v1prm v2prm v3prm
1: 1 2 9 0 0 9 0
2: 2 7 4 8 7 1 8
3: 3 5 10 9 5 10 9
4: 4 1 8 1 1 8 1
5: 5 6 0 0 6 0 1
6: 6 8 7 0 8 7 0
7: 7 0 0 6 0 0 2
And I want to compare numberwise each column with its 'prm', as follows:
fill[v1==v1prm & v2==v2prm & v3==v3prm]
So the output is:
> fill[v1==v1prm & v2==v2prm & v3==v3prm]
n v1 v2 v3 v1prm v2prm v3prm
1: 3 5 10 9 5 10 9
2: 4 1 8 1 1 8 1
3: 6 8 7 0 8 7 0
But I do not want to hardcode this because I might use more than 3 columns. Also, I may want to use other comparison, such as...
> fill[v1>v1prm & v2==v2prm & v3==v3prm]
n v1 v2 v3 v1prm v2prm v3prm
1: 1 2 9 0 0 9 0
r boolean data.table logic
r boolean data.table logic
edited Jan 2 at 0:30
wolfsatthedoor
asked Jan 2 at 0:24


wolfsatthedoorwolfsatthedoor
1,627102959
1,627102959
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Using a functional approach here via Map
:
## set some variable names
pre <- paste0("v", 1:3)
pst <- paste0(pre, "prm")
## select where they match using `==` and Reduce to combine with a `&` (logical AND)
fill[Reduce(`&`, Map(`==`, mget(pre), mget(pst)))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 3 5 10 9 5 10 9
#2: 4 1 8 1 1 8 1
#3: 6 8 7 0 8 7 0
Extending this logic to loop over different logical comparisons:
funs <- c(`>`, `==`, `==`)
fill[Reduce(`&`, Map(function(pr,ps,f) f(pr,ps), mget(pre), mget(pst), funs))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 1 2 9 0 0 9 0
add a comment |
Functional approach answer is cool, but I prefer the pedestrian eval/parse
instead here since it's easier to read/maintain:
lhs = paste0('v', 1:3)
fns = c('>', '==', '==')
rhs = paste0(pre, 'prm')
fill[eval(parse(text = paste(lhs, fns, rhs, collapse = '&')))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 1 2 9 0 0 9 0
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54000008%2fmultiple-flexible-logical-column-comparison-in-data-table%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Using a functional approach here via Map
:
## set some variable names
pre <- paste0("v", 1:3)
pst <- paste0(pre, "prm")
## select where they match using `==` and Reduce to combine with a `&` (logical AND)
fill[Reduce(`&`, Map(`==`, mget(pre), mget(pst)))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 3 5 10 9 5 10 9
#2: 4 1 8 1 1 8 1
#3: 6 8 7 0 8 7 0
Extending this logic to loop over different logical comparisons:
funs <- c(`>`, `==`, `==`)
fill[Reduce(`&`, Map(function(pr,ps,f) f(pr,ps), mget(pre), mget(pst), funs))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 1 2 9 0 0 9 0
add a comment |
Using a functional approach here via Map
:
## set some variable names
pre <- paste0("v", 1:3)
pst <- paste0(pre, "prm")
## select where they match using `==` and Reduce to combine with a `&` (logical AND)
fill[Reduce(`&`, Map(`==`, mget(pre), mget(pst)))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 3 5 10 9 5 10 9
#2: 4 1 8 1 1 8 1
#3: 6 8 7 0 8 7 0
Extending this logic to loop over different logical comparisons:
funs <- c(`>`, `==`, `==`)
fill[Reduce(`&`, Map(function(pr,ps,f) f(pr,ps), mget(pre), mget(pst), funs))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 1 2 9 0 0 9 0
add a comment |
Using a functional approach here via Map
:
## set some variable names
pre <- paste0("v", 1:3)
pst <- paste0(pre, "prm")
## select where they match using `==` and Reduce to combine with a `&` (logical AND)
fill[Reduce(`&`, Map(`==`, mget(pre), mget(pst)))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 3 5 10 9 5 10 9
#2: 4 1 8 1 1 8 1
#3: 6 8 7 0 8 7 0
Extending this logic to loop over different logical comparisons:
funs <- c(`>`, `==`, `==`)
fill[Reduce(`&`, Map(function(pr,ps,f) f(pr,ps), mget(pre), mget(pst), funs))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 1 2 9 0 0 9 0
Using a functional approach here via Map
:
## set some variable names
pre <- paste0("v", 1:3)
pst <- paste0(pre, "prm")
## select where they match using `==` and Reduce to combine with a `&` (logical AND)
fill[Reduce(`&`, Map(`==`, mget(pre), mget(pst)))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 3 5 10 9 5 10 9
#2: 4 1 8 1 1 8 1
#3: 6 8 7 0 8 7 0
Extending this logic to loop over different logical comparisons:
funs <- c(`>`, `==`, `==`)
fill[Reduce(`&`, Map(function(pr,ps,f) f(pr,ps), mget(pre), mget(pst), funs))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 1 2 9 0 0 9 0
answered Jan 2 at 0:39
thelatemailthelatemail
68k883151
68k883151
add a comment |
add a comment |
Functional approach answer is cool, but I prefer the pedestrian eval/parse
instead here since it's easier to read/maintain:
lhs = paste0('v', 1:3)
fns = c('>', '==', '==')
rhs = paste0(pre, 'prm')
fill[eval(parse(text = paste(lhs, fns, rhs, collapse = '&')))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 1 2 9 0 0 9 0
add a comment |
Functional approach answer is cool, but I prefer the pedestrian eval/parse
instead here since it's easier to read/maintain:
lhs = paste0('v', 1:3)
fns = c('>', '==', '==')
rhs = paste0(pre, 'prm')
fill[eval(parse(text = paste(lhs, fns, rhs, collapse = '&')))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 1 2 9 0 0 9 0
add a comment |
Functional approach answer is cool, but I prefer the pedestrian eval/parse
instead here since it's easier to read/maintain:
lhs = paste0('v', 1:3)
fns = c('>', '==', '==')
rhs = paste0(pre, 'prm')
fill[eval(parse(text = paste(lhs, fns, rhs, collapse = '&')))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 1 2 9 0 0 9 0
Functional approach answer is cool, but I prefer the pedestrian eval/parse
instead here since it's easier to read/maintain:
lhs = paste0('v', 1:3)
fns = c('>', '==', '==')
rhs = paste0(pre, 'prm')
fill[eval(parse(text = paste(lhs, fns, rhs, collapse = '&')))]
# n v1 v2 v3 v1prm v2prm v3prm
#1: 1 2 9 0 0 9 0
answered Jan 2 at 20:15
eddieddi
42.6k575130
42.6k575130
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54000008%2fmultiple-flexible-logical-column-comparison-in-data-table%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown