简体   繁体   中英

Why there is no output when I do R Pattern Matching with For loop

This is the first time I wrote a R function. What I want to do is for example I have a R data.frame like this

                             Vars        match
1                             A_m          0
2                             B_m          0
3                               C          0
4                               D          34
5                               E_m        0

This is the result I got after matching two dataframes. In the match column, if the number is 0, it means there is no match for the value in the Vars column. For example in first row, A_m has 0 in match column. This means A_m doesn't have a match. So my function is to find those values in Vars column that has no match (has 0 in match column). After that if the value I found ends with "_m" then it is the value I want, and I want to print them out.

This is the code I wrote. Because I have never written R function before, there can be lots of problems with my code. I want to use data.frame as my function's argument and use for loop to check the whole dataframe. In the for loop I want to use if to decide whether it is the target value or not. Really appreciate for your help and Patience.

varsConvert <- function(x){
  for(i in 1:nrow(x)){
    #x[i,1]is the cordinate of the value in that dataframe, can I write like this?
    if(x[i,1] == 0){
      #I want to match ends with _m by *_m
      if(x[i,0] == "*_m"){
        print(x[i,0])
      }
      else if(x[i,0] == "E"){
          print(x[i,0])
        }
      else{
        stop("this is an error")
      }

    }
  }
}

In my example the values I want to print should be A_m, B_m and E_m

While it is possible to write "classic" for loops in R, it's often best to use other functions which will be shorter/cleaner/faster. Here is your data (I named it df ) :

df<-structure(list(Vars = c("A_m", "B_m", "C", "D", "E_m"), match = c(0L, 
0L, 0L, 34L, 0L)), .Names = c("Vars", "match"), class = "data.frame", row.names = c(NA, 
-5L))

You can do :

temp<-df$Vars[df$match==0] # find the names of Vars for which match is equal to 0
temp[grep('_m',temp)] # only select those with _m
# [1] "A_m" "B_m" "E_m"

An other option is to select the indexes of the intersection of match==0 and _m in Vars :

df$Vars[intersect(grep('_m',df$Vars),which(df$match==0))]
# [1] "A_m" "B_m" "E_m"

And yet another approach (using Boolean arithmetic rather than set operations):

df$Vars[ grepl('_m',df$Vars) & df$match==0 ]

If you want a function with a data.frame in input you can do this (I used column numbers this time to show other possibilities) :

f<-function(data){
    temp<-data[,1][data[,2]==0]
    temp[grep('_m',temp)]
}

To use it, call f(nameOfYourData) :

f(df)
# [1] "A_m" "B_m" "E_m"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM