"Replacement has 1 row, data has 0" when creating a function, that returns values from data frame.

I'm creating a custom function, to take a closer look into data frames, that have election results in them. Columns consist of political parties and he rows consist of electoral district. My custom function takes two arguments: The data frame (df) and the district (region). The function is supposed to return three biggest parties in the given district, and the percentage of vote each party got.

I've run into a problem with the function. While my function works wonderfully when given a region that does exist within the data frame, it does not however print the else command given within the function when region does not exist. Instead of returning "Region does not exist", it instead gives me Error in [<-.data.frame(*tmp*, , 1, value = NA) :
replacement has 1 row, data has 0

This is an error I'm not familiar with, and googling it only seems to indicate to me that the error is unique to the case. Thus, what am I missing in my function? I guess I've become blind to the function since I've been looking at it for a while. How can I fix this error?

top3 <- function(df, region){
rownames <- df[,1]
df <- as.data.frame(df, row.names = rownames)
aapo <- subset(df, Alue == region)
aapo[,1] <- NA
aapo[,22] <- NA
TT <- sort(aapo, decreasing = TRUE)
tulos <- head(TT)[1:3]
if (alue %in% rownames) {
result <- tulos
} else {
result <- "Region does not exist"
}
return(result)
}

The standard way to ask this type of question in this group is to create a reproducible example.
Please have a look at that. When you add to your code (a small version of) your data it becomes much easier for us to see what goes wrong. If data is confidential just make it up with fake data as long as the structure of the data is the same.

Looking only at your function:
the error indicates the line
aapo[,1] <- NA
If there are no rows in aapo (because the region is not in the table) this line will fail.
So first check if the number of rows is zero:

aapo <- subset(df, Alue == region)
if (nrow(aapo) == 0) return("Region does not exist")
...

You need your if() conditional argument before trying to subset the data.

tmydata <- data.frame(Alue = c("A", "B"), 
                     pp1 = c(10, 5), 
                     pp2 = c(60, 30), 
                     pp3 = c(2, NA),
                     pp4 = c(28, 63))

top3 <- function(df, region){
  rownames(df) <- df[,1]
  
  if (region %in% rownames(df)) {
    aapo <- subset(df, Alue == region)
    aapo[,1] <- NA
    #aapo[,22] <- NA  # only turned off for reprex
    TT <- sort(aapo, decreasing = TRUE)
    tulos <- head(TT)[1:3]
    return(tulos)
  } else 
      print("Region does not exist")
}

top3(mydata, "A")  # gives results
top3(mydata, "C")  # gives error messages
1 Like

It's less about the if() statement and more about the order that code executes. The code runs top to bottom, one command at a time (most of the time). So when you called Alue == "unrecognizable_region" prior to the if() statement, the code gave an error message. In R, when an error message is reached, the entire thing stops.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

Thanks @jpiaskowski.
With your example data I see that the sort and head do work in this case (because the result of the subset is a one-row table).

Ahh, my bad! I'm new here and maybe was too eager to get help on this, since I've been stuck on this for few days. I'm quite new to R so it is quite overwhelming... I appreciate your help and advice, and will improve in future!

Glad it worked. I think you can omit head() and use TT[,1:3] to get the same results.

Thank you mate! This solved it. If-function has always been quite confusing to me, and thus Im not suprised the problem was the if function :slight_smile:

1 Like