SCDCE
SCDCE

Reputation: 1643

How to generate an R table() using duplicate values grouped by ID for use in a for-loop

I have duplicate values for "Type" but they are associated with group ID codes.

Type <- data.frame("Type" = c("A","A","A","B","B","B","B","C","C","C","C"), 
                   "ID"= c(1,1,1,2,2,2,2,3,3,4,4))
t <- table(Type[c("Type", "ID")])

a <- as.character()

I'm wanting to put this into a for-loop to generate a sentence.

for(i in 1:length(t)) {
  if(i == 1){
    a <- c(a,   
           paste0("One was associated with ", 
              names(t)[i], " (", 
              t[i]), "cases)")
    if(length(t) > 2){
      a <- paste0(a, ",")
    }
  }

  if(i < length(t) & i > 1){
a <- c(a,   
       paste0("one was associated with ", 
              names(t)[i], " (", 
              t[i]), "cases),")
  } else if (i == length(t)){
a <- c(a,   
       paste0("and one was associated with ", 
              names(t)[i], " (", 
              t[i]), "cases).")

  }
}

a <- capture.output(cat(a))
a

I've been playing around with

table(Type[c("Type", "ID")])

but now I'm stuck generating:

[1] "One was associated with  (3, cases), one was associated with  (0 cases), one was associated with  (0 cases), one was associated with  (0 cases), one was associated with  (4 cases), one was associated with  (0 cases), one was associated with  (0 cases), one was associated with  (0 cases), one was associated with  (2 cases), one was associated with  (0 cases), one was associated with  (0 cases), and one was associated with  (2 cases)."

Whereas I want my final product displaying as this:

[1] "One was associated with  A (3 cases), one was associated with B (4 cases), one was associated with C (2 cases), one was associated with C (2 cases).

I've had success manipulating the for-loop for various types of data but never any grouped data.

I went for this solution:

Library(Hmisc)
Library(stringi)

Type <- data.frame("Type" = c("A","A","A","B","B","B","B","C","C","C","C"), "ID"= c(1,1,1,2,2,2,2,3,3,4,4))
t <- table(Type)
a <- as.character()
for(i in 1:nlevels((as.factor(Type$ID)))){
  a <- paste0(a,"one was associated with"," ", sep = "")
  for(j in 1:nlevels(as.factor(Type$Type))){
    if(t[j,i] > 0){
      a <- paste0(a,levels(Type$Type)[j]," (",t[j,i]," cases),",sep = " ")
    }
  }
}

a <- capture.output(cat(a))
a <- substr(a, 1, nchar(a)-2)
a <- paste0(a, ".")
if(length(table(Type$ID)) <3){
  a <- sub(",", "", a)
}
a <- stri_replace_last_regex(a, "one", "and one",  opts_regex = list())
a <- capitalize(a)
a

[1] "One was associated with A (3 cases), one was associated with B (4 cases), one was associated with C (2 cases), and one was associated with C (2 cases)."

And to test functionality:

Type <- data.frame("Type" = c("A","A","A","B","B","B","B"), "ID"= c(1,1,1,2,2,2,2))

[1] "One was associated with A (3 cases) and one was associated with B (4 cases)."

Upvotes: 0

Views: 54

Answers (2)

Wietze314
Wietze314

Reputation: 6020

As mentioned in the comments, but then using dplyr:

library(dplyr)

sen <- Type %>% group_by(Type, ID) %>% summarise(n = n()) %>%
  mutate(sentence = paste0("one was associated with ",Type," (",n," cases)"))
paste(sen$sentence, collapse = ", ")

Upvotes: 1

Sp&#228;tzle
Sp&#228;tzle

Reputation: 747

I think you should iterate over the table (note that you should simply call a table of the df, nothing more) and then ignore nulls:

Type <- data.frame("Type" = c("A","A","A","B","B","B","B","C","C","C","C"), "ID"= c(1,1,1,2,2,2,2,3,3,4,4))
t <- table(Type)
a <- as.character()
for(i in 1:nlevels((as.factor(Type$ID)))){
  a <- paste(a,"One was associated with ",sep = "")
  for(j in 1:nlevels(as.factor(Type$Type))){
    if(t[j,i] > 0){
      a <- paste(a,levels(Type$Type)[j],"(",t[j,i],"cases),",sep = " ")
    }
  }
}

the output is

[1] "One was associated with  A ( 3 cases),One was associated with  B ( 4 cases),One was associated with  C ( 2 cases),One was associated with  C ( 2 cases),"

and I'm sure you'll be able to apply the corrections for unneccesary spaces and commas.

Upvotes: 1

Related Questions