user8248672
user8248672

Reputation:

Running an ifelse() in lists

I have this list here:

 structure(list(`1` = c("4", "*", ".", ".", "*", ".", ".", "*", 
"*", ".", "*", ".", ".", ".", ".", ".", "."), `2` = c("5", ".", 
".", ".", ".", ".", "*", ".", ".", ".", "*", ".", ".", ".", ".", 
"*", ".", "*", ".", ".", "*", "*", "*", "*", "*", "."), `3` = c("4", 
".", ".", ".", ".", "*", ".", ".", "*", ".", ".", "a", "*", ".", 
"*", ".", ".")), .Names = c("1", "2", "3"))

I would like to change the symbols (* and .) to numbers (* to a 0 and . to a 1) inside each list.

Incidentally, if any thing else than a symbol comes up (like a letter), than I would like the list to print NA.

I've tried this, which doesn't change anything...

ifelse(board_split_vec == "*", 0, 
      ifelse(board_split_vec == ".", 1, board_split_vec))

Ideally, I have to find a way to do this using Base R functions..no packages please!

Upvotes: 1

Views: 90

Answers (3)

IRTFM
IRTFM

Reputation: 263342

This would be fairly efficient. Assignment via logical indexing:

  ( board_split_vec <- lapply( board_split_vec, 
                   function(x){ x[ x=="*"] <- 0; x[x=="."] <- 1; as.numeric(x)}) ) 
$`1`
 [1] 4 0 1 1 0 1 1 0 0 1 0 1 1 1 1 1 1

$`2`
 [1] 5 1 1 1 1 1 0 1 1 1 0 1 1 1 1 0 1 0 1 1 0 0 0 0 0 1

$`3`
 [1]  4  1  1  1  1  0  1  1  0  1  1 NA  0  1  0  1  1

Upvotes: 0

lmo
lmo

Reputation: 38500

You could also use lapply and match like this:

lapply(x, function(y) match(y, table=c(".","*", "2", "3", "4", "5")) - 1L)

This returns:

$`1`
 [1] 4 1 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0

$`2`
 [1] 5 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 1 1 1 1 0

$`3`
 [1]  4  0  0  0  0  1  0  0  1  0  0 NA  1  0  1  0  0

We use the positions returned by match and then subtract 1 to get the desired 0, 1 returns. When an element is not in the table argument of match, it returns NA by default.

Note that if there are pre-existing 0s and 1s, then this method won't work. Also, if the actual vectors are quite long, or if there are a large number of vectors in your list, you should take a look at the fastmatch package.

Upvotes: 3

Martin Schmelzer
Martin Schmelzer

Reputation: 23889

You can use lapply:

lapply(df, function(x) {
  x <- ifelse(x == "*", 0,  ifelse(x == ".", 1, x))
  gsub("[^*\\.]", NA, x)  
})

Upvotes: 1

Related Questions