1

I'm trying to write a Shiny App in R that let's users see their individual survey results based on a participant code. Unfortunately the participant code starts with a number (e.g. 01ABAB01) so renaming duplicate rows with make.names will also result in an X in front of all the codes (e.g. X01ABAB0). Now the codes are needed for participants to adress their data so they'd ideally be exactly what participants originally typed in (I could in theory tell participants to put an X in front of their code, but that wouldn't be exactly elegant). So I'm looking for a way to either avoid the renaming (while still getting unique rownames), to undo the renaming or to have users input the original Code but still have shiny call the correct row. I tried Data[paste("X",input$Code), "SP03_01"] and some variations of that but it would result in "Your result is NA".


Data <- read.csv("Daten2.csv", header= TRUE, sep = ";", na.strings=c("",".","NA"), skipNul = TRUE)

rownames (Data)= make.names (Daten$IN04_05, unique = TRUE)


ui <- fluidPage(
  titlePanel("Your results"),
  sidebarLayout(
    sidebarPanel(
  textInput(inputId = "Code", label= "Please enter your code", placeholder= "z.B. 01ABAB01"),
  actionButton (inputId = "Button", label = "Show my results"),
  mainPanel(textOutput(outputId = "Example"))
)

)
server<-function(input,output){
  output$Example<-eventReactive(
    input$Button, {print(paste("Your result is ", Data[input$Code, "SP03_01"]))}
  )
}
shinyApp(ui=ui, server=server)

Any ideas? I've been truly stuck with this bit for some reason :P

Ninke
  • 247
  • 1
  • 12
  • 1
    The premise of `make.names` is primarily for *column names* or *object names*, but it doesn't really apply to the concept of row names. Try using `make.unique(Daten$IN04_05)` instead, it does not prepend `X` to strings that are normally not "legal R object names". (Or don't use row names, there are many arguments against their use, some are not subjective.) – r2evans Jul 13 '21 at 13:23
  • Thanks for the advice. I actually googled methods to make rownames unique and the other post told me to use make.names but make.unique works much better. I think for my purpose- referring to participant data by using their pseudonym as an input - rownames are an easy way. What would be the main reasons to avoid rownames in your experience? – Ninke Jul 14 '21 at 13:38
  • 1
    Sure, a few detractors: many functions (notably most of the tidyverse, but still many others) ignore or discard row names; summarizing/aggregation does not keep them or a rendition of them in any reliable fashion; some people try to use them like numeric indices, so a row name of `5` is actually `"5"`, but mistaken code can still try `mydat[5,]` and *will get results* albeit likely to be incorrect, `mydat["5",]` would be better. Those are a few. I agree that they can be useful, but know their limitations. – r2evans Jul 14 '21 at 13:57

2 Answers2

2

make.names is intended to make names that are legal for R objects and frame column names. It might be better to use just make.unique (which is used by make.names(.., unique=TRUE)): it does not enforce the constraint that names cannot begin with numbers, for instance.

Good discussions/references on naming convention and the use of make.names:

make.unique(c("01ABAB01", "01ABAB01"))
# [1] "01ABAB01"   "01ABAB01.1"

This demonstrates what will happen with duplicate names; it still munges the duplicates (by definition/purpose), but at least it still starts with the same substring.

r2evans
  • 141,215
  • 6
  • 77
  • 149
1

One way would be to use substr and remove the first character (X) from the rownames

rownames(Data) <- substr(rownames(Data),2,nchar(rownames(Data)))

  • Thanks. I considered doing it like that (although as an R newbie I didn't know how to do it yet), but it turns out using make.unique instead of make.names like @r2evans suggested fixes the issue within the rownames command already :) – Ninke Jul 14 '21 at 13:43