1

I'm trying to write an R function that will produce a string for later output. The data comes in a dataframe with one column and rownames.

fcc <- structure(list(temp = structure(c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 1L, 3L, 3L, 3L, 4L, 3L, 3L, 3L, 3L, 3L, 2L, 3L, 3L, 3L, 
3L, 3L, 3L, 4L, 3L, 4L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
4L, 4L, 1L, 3L, 3L, 4L, 4L, 1L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L
), .Label = c("H", "M", "N", "S"), class = "factor")), 
.Names = "temp", row.names = 
  c(NA, 135L), class = c("tbl_df", "tbl", "data.frame"))

outStr <- "name"
for(i in 1:nrow(fcc)){
 if (fcc[i,] != "N"){
   outStr <- paste0(outStr," ", rownames(fcc)[i],"(",fcc[i,],")") 
 }
}

Instead of the characters "H","M", etc. that I expect R returns 1,2,etc.

When I type in fcc[i] at the command prompt I can see the character I need:

 > fcc[1,]
 Source: local data frame [1 x 1]

  temp
  1    N

I am pretty sure this is me misunderstanding factors, but I can't figure it out.

Thanks! Matt

1 Answer 1

4

Actually your object isn't a "regular" data.frame. It's a tbl_df probably created from dplyr. Looks like this class has different subsetting rules. With normal data.frames, when you subset and only one column is returned, then the result is converted to a vector.

Look at the differences when you subset a tbl_df object and a standard data.frame

fcc2 <- as.data.frame(fcc)
str(fcc[1,])
# Classes ‘tbl_df’ and 'data.frame':    1 obs. of  1 variable:
#  $ temp: Factor w/ 4 levels "H","M","N","S": 3
str(fcc2[1,])
# Factor w/ 4 levels "H","M","N","S": 3
str(fcc2[1,, drop=F])
# 'data.frame': 1 obs. of  1 variable:
#  $ temp: Factor w/ 4 levels "H","M","N","S": 3

As discussed on the ?paste help page, values are converted to characters via as.character. Which ultimately appears to attempt the conversion via as.vector(, mode="character") which is what is changing your value to character versions of the numeric index.

as.vector(fcc[1,1], "character")
# [1] "3"
as.vector(fcc2[1,1], "character")
# [1] "N"

Note also that your look really isn't necessary, you can index/subset/collapse all in vectorized operations.

paste(paste0(seq_along(fcc[[1]]), "(", fcc[[1]] , ")")[fcc[[1]]!="N"], collapse=" ")

Here we use [[ ]] to extract the factor vector from the tbl_df object so pasting works much better.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.