Appending values with different order in R - r

I have two data elements in R:
data1
1 M
2 T
3 Z
4 A
5 J
data2 values
[1,] "A" "aa"
[2,] "J" "ab"
[3,] "M" "ac"
[4,] "T" "ad"
[5,] "Z" "ae"
I would like to get:
data1 values
[1,] "M" "ac"
[2,] "T" "ad"
[3,] "Z" "ae"
[4,] "A" "aa"
[5,] "J" "ab"
How can I append the values to data 1 such that they are sorted according to the different order in data 1?

You can get this behavior with the match function:
dat1 = data.frame(data1=c("M", "T", "Z", "A", "J"), stringsAsFactors=FALSE)
dat2 = data.frame(data2=c("A", "J", "M", "T", "Z"),
values=c("aa", "ab", "ac", "ad", "ae"), stringsAsFactors=FALSE)
dat2[match(dat1$data1, dat2$data2),]
# data2 values
# 3 M ac
# 4 T ad
# 5 Z ae
# 1 A aa
# 2 J ab

Related

Reshape 2d into 3d matrix with rows as columns and columns as the 3rd dimension

How would I reshape a matrix where I'd need every 2 rows to start a new column and every column to be in the third dimension in R? I haven't really tried anything outside of dim() which obviously didn't work, as I'm having a hard time wrapping my head around this transformation.
What I have:
d h
c g
b f
a e
What I want:
[ , , 1]
b d
a c
[ , , 2]
g h
e f
I think you can get the required structure of your matrix adjusting the dim attribute.
I added two additional rows to your matrix, it looks like this :
mat <- structure(c("d", "c", "b", "a", "k", "l", "h", "g", "f", "e",
"j", "m"), .Dim = c(6L, 2L))
mat
# [,1] [,2]
#[1,] "d" "h"
#[2,] "c" "g"
#[3,] "b" "f"
#[4,] "a" "e"
#[5,] "k" "j"
#[6,] "l" "m"
To get every column into 3rd dimension and only 2 values in each column you can do :
dim(mat) <- c(2, nrow(mat)/2, ncol(mat))
mat
#, , 1
# [,1] [,2] [,3]
#[1,] "d" "b" "k"
#[2,] "c" "a" "l"
#, , 2
# [,1] [,2] [,3]
#[1,] "h" "f" "j"
#[2,] "g" "e" "m"
We can use array
array(t(df1), c(2, 2, 2))

Applying split function to overlapping rows of a matrix

Suppose I have a matrix which looks like this:
[1] a b c
[2] d e f
[3] g h i
[4] j k l
[5] m n o
[6] p q r
Now I want to split this matrix into smaller ones with each 3 rows, starting from the first row, then the second, ..., so it looks like this in the end:
[1] a b c
[2] d e f
[3] g h i
[1] d e f
[2] g h i
[3] j k l
[1] g h i
[2] j k l
[3] m n o
...
I tried the following code, which didn't do it for me:
lapply(split(1:nrow(matrix),(1:nrow(matrix)-1) %/%3+1),
function(i) matrix[i,])
Can someone help me with this?
The split method showed in the OP's post will split into blocks of 3 rows and that will not be mutually exclusive. Whereas if we want to split in a way that each list element starts with each of the rows of the matrix and the next two rows, we can loop through the sequence of rows, get the sequence from that index to the next two and subset the matrix
lapply(head(seq_len(nrow(matrix)), -2), function(i) matrix[i:(i+2),])
#[[1]]
# [,1] [,2] [,3]
#[1,] "a" "b" "c"
#[2,] "d" "e" "f"
#[3,] "g" "h" "i"
#[[2]]
# [,1] [,2] [,3]
#[1,] "d" "e" "f"
#[2,] "g" "h" "i"
#[3,] "h" "k" "l"
#[[3]]
# [,1] [,2] [,3]
#[1,] "g" "h" "i"
#[2,] "h" "k" "l"
#[3,] "m" "n" "o"
[[4]]
[,1] [,2] [,3]
[1,] "h" "k" "l"
[2,] "m" "n" "o"
[3,] "p" "q" "r"
Or as #lmo suggested, another version of the above would be
lapply(seq_len(nrow(matrix) -2L) - 1L, function(x) matrix[x + 1:3,])
or another option is to create the splitting group with rollapply (from zoo) and then do the split
library(zoo)
grp <- rollapply(seq_len(nrow(matrix)), 3, FUN = I)
lapply(split(grp, row(grp)), function(i) matrix[i, ])
NOTE: matrix is a function name. It is better not to name objects with function names or other reserved words
data
matrix <- structure(c("a", "d", "g", "h", "m", "p", "b", "e", "h", "k",
"n", "q", "c", "f", "i", "l", "o", "r"), .Dim = c(6L, 3L))

How to convert list file to matrix

I have a list file as below:
> results
[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
[[1]][[1]][[1]][[1]]
[1] "1" "inflammation" "37.5" "A" "B"
[6] "F"
[[1]][[1]][[2]]
[[1]][[1]][[2]][[1]]
[1] "1" "Apoptosis" "37.5" "C" "G" "H"
[[1]][[1]][[3]]
[[1]][[1]][[3]][[1]]
[1] "1" "Repair" "25" "A" "H"
[[2]]
[[2]][[1]]
[[2]][[1]][[1]]
[[2]][[1]][[1]][[1]]
[1] "2" "inflammation" "20" "F"
[[2]][[1]][[2]]
[[2]][[1]][[2]][[1]]
[1] "2" "Apoptosis" "40" "G" "H"
[[2]][[1]][[3]]
[[2]][[1]][[3]][[1]]
[1] "2" "Repair" "20" "H"
Also this is the output of dput function:
dput(results)
list(list(list(list(c("1", "inflammation", "37.5", "A", "B",
"F")), list(c("1", "Apoptosis", "37.5", "C", "G", "H")), list(
c("1", "Repair", "25", "A", "H")))), list(list(list(c("2",
"inflammation", "20", "F")), list(c("2", "Apoptosis", "40", "G",
"H")), list(c("2", "Repair", "20", "H")))), list(list(list(c("3",
"inflammation", "25", "F")), list(c("3", "Apoptosis", "25", "C"
)), list(c("3", "Repair", "0")))), list(list(list(c("4", "inflammation",
"50", "A", "B", "F")), list(c("4", "Apoptosis", "33.3333333333333",
"G", "H")), list(c("4", "Repair", "33.3333333333333", "A", "H"
)))))
Then I want to make a matrix like this
Number pathway wight genes
1 inflammation 37.5 A, B, F
1 Apoptosis 37.5 C, G, H
1 Repair 25 A, H
2 inflammation 20 F
2 Apoptosis 40 G, H
2 Repair 20 H
Is there any trick for this? genes columns includes various number of genes.
First you should unlist the results a few times. Then you have to paste the genes together and finally you can rbind the data. Here's how this could look like.
lst <- unlist(unlist(unlist(results, recursive=FALSE), recursive=FALSE), recursive=FALSE)
df <- do.call(rbind, lapply(lst,
function(x){
data.frame(Number=as.numeric(x[1]),
pathway=x[2],
weight=as.numeric(x[3]),
genes=paste(x[4:max(4, length(x))], collapse=", "))
}))
df
## Number pathway weight genes
## 1 1 inflammation 37.50000 A, B, F
## 2 1 Apoptosis 37.50000 C, G, H
## 3 1 Repair 25.00000 A, H
## 4 2 inflammation 20.00000 F
## 5 2 Apoptosis 40.00000 G, H
## 6 2 Repair 20.00000 H
## 7 3 inflammation 25.00000 F
## 8 3 Apoptosis 25.00000 C
## 9 3 Repair 0.00000 NA
## 10 4 inflammation 50.00000 A, B, F
## 11 4 Apoptosis 33.33333 G, H
## 12 4 Repair 33.33333 A, H
I would probably approach the issue at hand like shadow did above, but here's also an alternative recursive implementation that does not fix the number of unlists, i.e. it can handle varying depth within the list of lists.
It just traverses the tree until it finds an element other than list and performs some specified formatting on it, and finally rbinds it all to a single matrix:
recurse.format <- function(
x,
format = function(z) { c(z[1:3], ifelse(length(z)>3, paste(z[4:length(z)], collapse=","), NA)) }
){
if(class(x) == "list"){
do.call("rbind", lapply(x, FUN=recurse.format))
}else{
format(x)
}
}
mat <- recurse.format(results)
colnames(mat) <- c("Number", "Pathway", "Weight", "Genes")
print(mat)
> print(mat)
Number Pathway Weight Genes
[1,] "1" "inflammation" "37.5" "A,B,F"
[2,] "1" "Apoptosis" "37.5" "C,G,H"
[3,] "1" "Repair" "25" "A,H"
[4,] "2" "inflammation" "20" "F"
[5,] "2" "Apoptosis" "40" "G,H"
[6,] "2" "Repair" "20" "H"
[7,] "3" "inflammation" "25" "F"
[8,] "3" "Apoptosis" "25" "C"
[9,] "3" "Repair" "0" NA
[10,] "4" "inflammation" "50" "A,B,F"
[11,] "4" "Apoptosis" "33.3333333333333" "G,H"
[12,] "4" "Repair" "33.3333333333333" "A,H"

Non-redundant version of expand.grid

The R function expand.grid returns all possible combination between the elements of supplied parameters. e.g.
> expand.grid(c("aa", "ab", "cc"), c("aa", "ab", "cc"))
Var1 Var2
1 aa aa
2 ab aa
3 cc aa
4 aa ab
5 ab ab
6 cc ab
7 aa cc
8 ab cc
9 cc cc
Do you know an efficient way to get directly (so without any row comparison after expand.grid) only the 'unique' combinations between the supplied vectors? The output will be
Var1 Var2
1 aa aa
2 ab aa
3 cc aa
5 ab ab
6 cc ab
9 cc cc
EDIT the combination of each element with itself could be eventually discarded from the answer. I don't actually need it in my program even though (mathematically) aa aa would be one (regular) unique combination between one element of Var1 and another of var2.
The solution needs to produce pairs of elements from both vectors (i.e. one from each of the input vectors - so that it could be applied to more than 2 inputs)
How about using outer? But this particular function concatenates them into one character string.
outer( c("aa", "ab", "cc"), c("aa", "ab", "cc") , "paste" )
# [,1] [,2] [,3]
#[1,] "aa aa" "aa ab" "aa cc"
#[2,] "ab aa" "ab ab" "ab cc"
#[3,] "cc aa" "cc ab" "cc cc"
You can also use combn on the unique elements of the two vectors if you don't want the repeating elements (e.g. aa aa)
vals <- c( c("aa", "ab", "cc"), c("aa", "ab", "cc") )
vals <- unique( vals )
combn( vals , 2 )
# [,1] [,2] [,3]
#[1,] "aa" "aa" "ab"
#[2,] "ab" "cc" "cc"
In base R, you can use this:
expand.grid.unique <- function(x, y, include.equals=FALSE)
{
x <- unique(x)
y <- unique(y)
g <- function(i)
{
z <- setdiff(y, x[seq_len(i-include.equals)])
if(length(z)) cbind(x[i], z, deparse.level=0)
}
do.call(rbind, lapply(seq_along(x), g))
}
Results:
> x <- c("aa", "ab", "cc")
> y <- c("aa", "ab", "cc")
> expand.grid.unique(x, y)
[,1] [,2]
[1,] "aa" "ab"
[2,] "aa" "cc"
[3,] "ab" "cc"
> expand.grid.unique(x, y, include.equals=TRUE)
[,1] [,2]
[1,] "aa" "aa"
[2,] "aa" "ab"
[3,] "aa" "cc"
[4,] "ab" "ab"
[5,] "ab" "cc"
[6,] "cc" "cc"
If the two vectors are the same, there's the combinations function in the gtools package:
library(gtools)
combinations(n = 3, r = 2, v = c("aa", "ab", "cc"), repeats.allowed = TRUE)
# [,1] [,2]
# [1,] "aa" "aa"
# [2,] "aa" "ab"
# [3,] "aa" "cc"
# [4,] "ab" "ab"
# [5,] "ab" "cc"
# [6,] "cc" "cc"
And without "aa" "aa", etc.
combinations(n = 3, r = 2, v = c("aa", "ab", "cc"), repeats.allowed = FALSE)
The previous answers were lacking a way to get a specific result, namely to keep the self-pairs but remove the ones with different orders. The gtools package has two functions for these purposes, combinations and permutations. According to this website:
When the order doesn't matter, it is a Combination.
When the order does matter it is a Permutation.
In both cases, we have the decision to make of whether repetitions are allowed or not, and correspondingly, both functions have a repeats.allowed argument, yielding 4 combinations (deliciously meta!). It's worth going over each of these. I simplified the vector to single letters for ease of understanding.
Permutations with repetition
The most expansive option is to allow both self-relations and differently ordered options:
> permutations(n = 3, r = 2, repeats.allowed = T, v = c("a", "b", "c"))
[,1] [,2]
[1,] "a" "a"
[2,] "a" "b"
[3,] "a" "c"
[4,] "b" "a"
[5,] "b" "b"
[6,] "b" "c"
[7,] "c" "a"
[8,] "c" "b"
[9,] "c" "c"
which gives us 9 options. This value can be found from the simple formula n^r i.e. 3^2=9. This is the Cartesian product/join for users familiar with SQL.
There are two ways to limit this: 1) remove self-relations (disallow repetitions), or 2) remove differently ordered options (i.e. combinations).
Combinations with repetitions
If we want to remove differently ordered options, we use:
> combinations(n = 3, r = 2, repeats.allowed = T, v = c("a", "b", "c"))
[,1] [,2]
[1,] "a" "a"
[2,] "a" "b"
[3,] "a" "c"
[4,] "b" "b"
[5,] "b" "c"
[6,] "c" "c"
which gives us 6 options. The formula for this value is (r+n-1)!/(r!*(n-1)!) i.e. (2+3-1)!/(2!*(3-1)!)=4!/(2*2!)=24/4=6.
Permutations without repetition
If instead we want to disallow repetitions, we use:
> permutations(n = 3, r = 2, repeats.allowed = F, v = c("a", "b", "c"))
[,1] [,2]
[1,] "a" "b"
[2,] "a" "c"
[3,] "b" "a"
[4,] "b" "c"
[5,] "c" "a"
[6,] "c" "b"
which also gives us 6 options, but different ones! The number of options is the same as above but it's a coincidence. The value can be found from the formula n!/(n-r)! i.e. (3*2*1)/(3-2)!=6/1!=6.
Combinations without repetitions
The most limiting is when we want neither self-relations/repetitions or differently ordered options, in which case we use:
> combinations(n = 3, r = 2, repeats.allowed = F, v = c("a", "b", "c"))
[,1] [,2]
[1,] "a" "b"
[2,] "a" "c"
[3,] "b" "c"
which gives us only 3 options. The number of options can be calculated from the rather complex formula n!/(r!(n-r)!) i.e. 3*2*1/(2*1*(3-2)!)=6/(2*1!)=6/2=3.
Try:
factors <- c("a", "b", "c")
all.combos <- t(combn(factors,2))
[,1] [,2]
[1,] "a" "b"
[2,] "a" "c"
[3,] "b" "c"
This will not include duplicates of each factor (e.g. "a" "a"), but you can add those on easily if needed.
dup.combos <- cbind(factors,factors)
factors factors
[1,] "a" "a"
[2,] "b" "b"
[3,] "c" "c"
all.combos <- rbind(all.combos,dup.combos)
factors factors
[1,] "a" "b"
[2,] "a" "c"
[3,] "b" "c"
[4,] "a" "a"
[5,] "b" "b"
[6,] "c" "c"
You can use a "greater than" operation to filter redundant combinations. This works with both numeric and character vectors.
> grid <- expand.grid(c("aa", "ab", "cc"), c("aa", "ab", "cc"), stringsAsFactors = F)
> grid[grid$Var1 >= grid$Var2, ]
Var1 Var2
1 aa aa
2 ab aa
3 cc aa
5 ab ab
6 cc ab
9 cc cc
This shouldn't slow down your code too much. If you're expanding vectors containing larger elements (e.g. two lists of dataframes), I recommend using numeric indices that refer to the original vectors.
TL;DR
Use comboGrid from RcppAlgos:
library(RcppAlgos)
comboGrid(c("aa", "ab", "cc"), c("aa", "ab", "cc"))
Var1 Var2
[1,] "aa" "aa"
[2,] "aa" "ab"
[3,] "aa" "cc"
[4,] "ab" "ab"
[5,] "ab" "cc"
[6,] "cc" "cc"
The Details
I recently came across this question R - Expand Grid Without Duplicates and as I was searching for duplicates, I found this question. The question there isn't exactly a duplicate, as it is a bit more general and has additional restrictions which #Ferdinand.kraft shined some light on.
It should be noted that many of the solutions here make use of some sort of combination function. The expand.grid function returns the Cartesian product which is fundamentally different.
The Cartesian product operates on multiple objects which may or may not be the same. Generally speaking, combination functions are applied to a single vector. The same can be said about permutation functions.
Using combination/permutation functions will only produce comparable results to expand.grid if the vectors supplied are identical. As a very simple example, consider v1 = 1:3, v2 = 2:4.
With expand.grid, we see that rows 3 and 5 are duplicates:
expand.grid(1:3, 2:4)
Var1 Var2
1 1 2
2 2 2
3 3 2
4 1 3
5 2 3
6 3 3
7 1 4
8 2 4
9 3 4
Using combn doesn't quite get us to the solution:
t(combn(unique(c(1:3, 2:4)), 2))
[,1] [,2]
[1,] 1 2
[2,] 1 3
[3,] 1 4
[4,] 2 3
[5,] 2 4
[6,] 3 4
And with repeats using gtools, we generate too many:
gtools::combinations(4, 2, v = unique(c(1:3, 2:4)), repeats.allowed = TRUE)
[,1] [,2]
[1,] 1 1
[2,] 1 2
[3,] 1 3
[4,] 1 4
[5,] 2 2
[6,] 2 3
[7,] 2 4
[8,] 3 3
[9,] 3 4
[10,] 4 4
In fact we generate results that are not even in the cartesian product (i.e. expand.grid solution).
We need a solution that creates the following:
Var1 Var2
[1,] 1 2
[2,] 1 3
[3,] 1 4
[4,] 2 2
[5,] 2 3
[6,] 2 4
[7,] 3 3
[8,] 3 4
I authored the package RcppAlgos and in the latest release v2.4.3, there is a function comboGrid which addresses this very problem. It is very general, flexible, and is fast.
First, to answer the specific question raised by the OP:
library(RcppAlgos)
comboGrid(c("aa", "ab", "cc"), c("aa", "ab", "cc"))
Var1 Var2
[1,] "aa" "aa"
[2,] "aa" "ab"
[3,] "aa" "cc"
[4,] "ab" "ab"
[5,] "ab" "cc"
[6,] "cc" "cc"
And as, #Ferdinand.kraft points out, sometimes the output may need to have duplicates excluded in a given row. For that, we use repetition = FALSE:
comboGrid(c("aa", "ab", "cc"), c("aa", "ab", "cc"), repetition = FALSE)
Var1 Var2
[1,] "aa" "ab"
[2,] "aa" "cc"
[3,] "ab" "cc"
comboGrid is also very general. It can be applied to multiple vectors:
comboGrid(rep(list(c("aa", "ab", "cc")), 3))
Var1 Var2 Var3
[1,] "aa" "aa" "aa"
[2,] "aa" "aa" "ab"
[3,] "aa" "aa" "cc"
[4,] "aa" "ab" "ab"
[5,] "aa" "ab" "cc"
[6,] "aa" "cc" "cc"
[7,] "ab" "ab" "ab"
[8,] "ab" "ab" "cc"
[9,] "ab" "cc" "cc"
[10,] "cc" "cc" "cc"
Doesn't need the vectors to be identical:
comboGrid(1:3, 2:4)
Var1 Var2
[1,] 1 2
[2,] 1 3
[3,] 1 4
[4,] 2 2
[5,] 2 3
[6,] 2 4
[7,] 3 3
[8,] 3 4
And can be applied to vectors of various types:
set.seed(123)
my_range <- 3:15
mixed_types <- list(
int1 = sample(15, sample(my_range, 1)),
int2 = sample(15, sample(my_range, 1)),
char1 = sample(LETTERS, sample(my_range, 1)),
char2 = sample(LETTERS, sample(my_range, 1))
)
dim(expand.grid(mixed_types))
[1] 1950 4
dim(comboGrid(mixed_types, repetition = FALSE))
[1] 1595 4
dim(comboGrid(mixed_types, repetition = TRUE))
[1] 1770 4
The algorithm employed avoids generating the entirety of the Cartesian product and subsequently removing dupes. Ultimately, we create a hash table using the Fundamental theorem of arithmetic along with deduplication as pointed out by user2357112 supports Monica in the answer to Picking unordered combinations from pools with overlap. All of this together with the fact that it is written in C++ means that it is fast and memory efficient:
pools = list(c(1, 10, 14, 6),
c(7, 2, 4, 8, 3, 11, 12),
c(11, 3, 13, 4, 15, 8, 6, 5),
c(10, 1, 3, 2, 9, 5, 7),
c(1, 5, 10, 3, 8, 14),
c(15, 3, 7, 10, 4, 5, 8, 6),
c(14, 9, 11, 15),
c(7, 6, 13, 14, 10, 11, 9, 4),
c(6, 3, 2, 14, 7, 12, 9),
c(6, 11, 2, 5, 15, 7))
system.time(combCarts <- comboGrid(pools))
user system elapsed
0.929 0.062 0.992
nrow(combCarts)
[1] 1205740
## Small object created
print(object.size(combCarts), unit = "Mb")
92 Mb
system.time(cartProd <- expand.grid(pools))
user system elapsed
8.477 2.895 11.461
prod(lengths(pools))
[1] 101154816
## Very large object created
print(object.size(cartProd), unit = "Mb")
7717.5 Mb
here's a very ugly version that worked for me on a similar problem.
AHP_code = letters[1:10]
temp. <- expand.grid(AHP_code, AHP_code, stringsAsFactors = FALSE)
temp. <- temp.[temp.$Var1 != temp.$Var2, ] # remove AA, BB, CC, etc.
temp.$combo <- NA
for(i in 1:nrow(temp.)){ # vectorizing this gave me weird results, loop worked fine.
temp.$combo[i] <- paste0(sort(as.character(temp.[i, 1:2])), collapse = "")
}
temp. <- temp.[!duplicated(temp.$combo),]
temp.
USING SORT
Just for fun, one can in principle also remove duplicates from expand.grid by combining sort and unique.
unique(t(apply(expand.grid(c("aa", "ab", "cc"), c("aa", "ab", "cc")), 1, sort)))
This gives:
[,1] [,2]
[1,] "aa" "aa"
[2,] "aa" "ab"
[3,] "aa" "cc"
[4,] "ab" "ab"
[5,] "ab" "cc"
[6,] "cc" "cc"
With repetitions (this won't work if you specify different vectors for different columns and for example values in the first column are always bigger than values in the second column):
> v=c("aa","ab","cc")
> e=expand.grid(v,v,stringsAsFactors=F)
> e[!apply(e,1,is.unsorted),]
Var1 Var2
1 aa aa
4 aa ab
5 ab ab
7 aa cc
8 ab cc
9 cc cc
Without repetitions (this requires using the same vector for each column):
> t(combn(c("aa","ab","cc"),2))
[,1] [,2]
[1,] "aa" "ab"
[2,] "aa" "cc"
[3,] "ab" "cc"
With repetitions and with different vectors for different columns:
> e=expand.grid(letters[25:26],letters[1:3],letters[2:3],stringsAsFactors=F)
> e[!duplicated(t(apply(e,1,sort))),]
Var1 Var2 Var3
1 y a b
2 z a b
3 y b b
4 z b b
5 y c b
6 z c b
7 y a c
8 z a c
11 y c c
12 z c c
Without repetitions and with different vectors for different columns:
> e=expand.grid(letters[25:26],letters[1:3],letters[2:3],stringsAsFactors=F)
> e=e[!duplicated(t(apply(e,1,sort))),]
> e[!apply(apply(e,1,duplicated),2,any),]
Var1 Var2 Var3
1 y a b
2 z a b
5 y c b
6 z c b
7 y a c
8 z a c

Subsetting matrices

Considering following vector res and matrix team.
the vector res represent indices, and I require to extract only those names whose index number is in vector res and gender="F".
I need to do this in R and as I am a newbie to R, could not resolve this.
res
[1] 2 12 16 5 6 19 17 14 9 4
team
names genders
[1,] "aa" "M"
[2,] "ab" "M"
[3,] "al" "M"
[4,] "alp" "M"
[5,] "amr" "F"
[6,] "and" "M"
[7,] "an" "M"
[8,] "anv" "F"
[9,] "as" "M"
[10,] "ed" "M"
[11,] "neh" "F"
[12,] "pan" "M"
[13,] "poo" "F"
[14,] "ra" "M"
[15,] "roh" "M"
[16,] "shr" "F"
[17,] "sub" "M"
[18,] "val" "M"
[19,] "xi" "M"
There are many ways to do this.
You could first pick which rows are in res:
team$names[res]
Then you can pick which ones have gender being "F":
team$names[res][ team$genders[res]=="F" ]
Note that team$genders[res] picks out the genders corresponding to the rows in res, and then you filter to only accept those that are female.
If you liked, you could do it the other way round:
team$names[ team$genders=="F" & (1:nrow(team) %in% res) ]
Here team$genders=="F" is a logical vector of length nrow(team), being TRUE whenever the gender is "F" and FALSE otherwise.
The 1:nrow(team) generates row numbers, and 1:nrow(team) %in% res is TRUE if the row number is in res.
The & says "make sure that the gender is "F" AND the row number is in res".
You could even do which(team$genders=="F") which returns a vector of row numbers for females, and then do:
team$names[ intersect( which(team$genders=="F") , res ) ]
where the intersect picks row numbers that are present in both res and the females.
And I'm sure people with think of more ways.
This should work if your team is either a matrix or a data.frame:
# emulate your data
team <- data.frame(names=LETTERS, genders=rep(c("M","F"), 13))
res <- 10:26
team[intersect(res, which(team[,"genders"]=="F")), "names"]
#[1] J L N P R T V X Z
#Levels: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
# Try with a matrix instead of data.frame
team <- as.matrix(team)
team[intersect(res, which(team[,"genders"]=="F")), "names"]
#[1] "J" "L" "N" "P" "R" "T" "V" "X" "Z"
The basic idea is to get the indices of the "F" gender rows (using which) and then use the set operation intersect to AND it with your res indices. There are also union and setdiff variants that can be useful at times.
team <- structure(c("aa", "ab", "al", "alp", "amr", "and", "an", "anv",
"as", "ed", "neh", "pan", "poo", "ra", "roh", "shr", "sub", "val",
"xi", "M", "M", "M", "M", "F", "M", "M", "F", "M", "M", "F",
"M", "F", "M", "M", "F", "M", "M", "M"), .Dim = c(19L, 2L), .Dimnames = list(
NULL, c("names", "genders")))
team[,"names"][ intersect( which(team[,"genders"]=="F") , res ) ]
#[1] "amr" "shr"
team[,"names"][ team[,"genders"]=="F" & 1:NROW(team) %in% res ]
#[1] "amr" "shr"

Resources