Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using lapply and the ifelse function in R

I'm having an issue in R where I can run an ifelse statement on elements in a list, but as soon as I place the ifelse statement within the lapply function, it no longer works.

Here's my example. I'm working with a list of three dataframes:

> dflist
[[1]]
  ID1 tID1
1  m1    1
2  m2    2
3  m3    3
4  m4    4
5  m5    5

[[2]]
  ID2 tID2
1  m7    7
2  m8    8
3  m9    9
4 m10   10
5 m11   11

[[3]]
  ID3 tID3
1 m13   13
2 m14   14
3 m15   15
4 m16   16
5 m17   17
6 m18   18

If a dataframe has an odd number of rows, I want R to label it "ODD". If the dataframe has an even number of rows, I just want R to output the same dataframe. I would like the output to be a list.

This works when I write standalone ifelse statements:

> ifelse(nrow(dflist[[1]])%%2==!0, "ODD", dflist[1])
[1] "ODD"

> ifelse(nrow(dflist[[3]])%%2==!0, "ODD", dflist[3])
[[1]]
  ID3 tID3
1 m13   13
2 m14   14
3 m15   15
4 m16   16
5 m17   17
6 m18   18

But I get an error message as soon I put it into an lapply statement.

> lapply(dflist, function(x) ifelse(nrow(dflist[[x]])%%2==!0, "ODD", dflist[x]))

 Error in dflist[[x]] : invalid subscript type 'list' 
> 

Any ideas for why this happens and how to fix it? Thank you

like image 846
dcossyleon Avatar asked Mar 10 '23 10:03

dcossyleon


2 Answers

When you use lapply, you then just reference the parameter of the anonymous function, rather than your original list name. So instead of doing:

  lapply(dflist, function(x) ifelse(nrow(dflist[[x]])%%2==!0, "ODD", dflist[x]))

You just need to change to reference the list items you are putting in the function, i.e. "x"; so it should be:

 lapply(dflist, function(x) ifelse(nrow(x)%%2==!0, "ODD", x))
like image 40
SolomonRoberts Avatar answered Mar 11 '23 22:03

SolomonRoberts


If we need to return either "ODD" or dataset, then use if/else

lapply(dflist, function(x) if(nrow(x)%%2==1) "ODD" else x)

data

dflist <- list(data.frame(col1 = 1:3, col2=4:6), data.frame(col1=1:4, col2=5:8))
like image 161
akrun Avatar answered Mar 12 '23 00:03

akrun