Using accumarray function on a specific dataset in the form of loop

I obtained this code thanks to @Yarnabrina involving accumarray function in order to convert the following input dataset

input<-data.frame(
                                                       A = c(1L, 3L, 4L, 6L),
                                                     A.1 = c(2L, 3L, 7L, 7L),
                                                       B = c(9L, 10L, 8L, 5L),
                                                     B.1 = c(9L, 10L, 9L, 6L),
                                                       C = c(3L, 5L, 7L, 10L),
                                                     C.1 = c(4L, 6L, 8L, 10L),
                                                 subject = as.factor(c("s_1", "s_2", "s_3", "s_4"))
                                            )

into another dataframe represented by a new matrix containing zeros and, eventually, 1 or 2 values in correspondence of the values for the variables A, B and C of the input dataset, as follows:

output<-(
                                                       A.1 = c(1L, 0L, 0L, 0L),
                                                       A.2 = c(1L, 0L, 0L, 0L),
                                                       A.3 = c(0L, 2L, 0L, 0L),
                                                       A.4 = c(0L, 0L, 1L, 0L),
                                                       A.5 = c(0L, 0L, 0L, 0L),
                                                       A.6 = c(0L, 0L, 0L, 1L),
                                                       A.7 = c(0L, 0L, 1L, 1L),
                                                       A.8 = c(0L, 0L, 0L, 0L),
                                                       A.9 = c(0L, 0L, 0L, 0L),
                                                      A.10 = c(0L, 0L, 0L, 0L),
                                                       B.1 = c(0L, 0L, 0L, 0L),
                                                       B.2 = c(0L, 0L, 0L, 0L),
                                                       B.3 = c(0L, 0L, 0L, 0L),
                                                       B.4 = c(0L, 0L, 0L, 0L),
                                                       B.5 = c(0L, 0L, 0L, 1L),
                                                       B.6 = c(0L, 0L, 0L, 1L),
                                                       B.7 = c(0L, 0L, 0L, 0L),
                                                       B.8 = c(0L, 0L, 1L, 0L),
                                                       B.9 = c(2L, 0L, 1L, 0L),
                                                      B.10 = c(0L, 2L, 0L, 0L),
                                                       C.1 = c(0L, 0L, 0L, 0L),
                                                       C.2 = c(0L, 0L, 0L, 0L),
                                                       C.3 = c(1L, 0L, 0L, 0L),
                                                       C.4 = c(1L, 0L, 0L, 0L),
                                                       C.5 = c(0L, 1L, 0L, 0L),
                                                       C.6 = c(0L, 1L, 0L, 0L),
                                                       C.7 = c(0L, 0L, 1L, 0L),
                                                       C.8 = c(0L, 0L, 1L, 0L),
                                                       C.9 = c(0L, 0L, 0L, 0L),
                                                      C.10 = c(0L, 0L, 0L, 2L),
                                                   subject = as.factor(c("s_1", "s_2", "s_3", "s_4"))
                                              )

I wrote the following code but I'd like to make it as a dynamic loop since the input table could contain a different number of variables (still with 2 values per variable).

required_subsA <- cbind(rep(x = 1:nrow(input),
                            times = 2),c(input$A,input$A.1))
required_vals <- rep(x = 1,
                     times = nrow(x = required_subs))
required_sz <- c(nrow(x = input), 10)

A <- cbind(paste("s", 1:4, sep = "_"),
           as.data.frame(x = pracma::accumarray(subs = required_subsA,
                                                val = required_vals,
                                                sz = required_sz)))
names(x = A) <- c("subject",paste("A", 1:10, sep = "."))

required_subsB <- cbind(rep(x = 1:nrow(input),
                            times = 2),c(input$B,input$B.1))

B <- cbind(as.data.frame(x = pracma::accumarray(subs = required_subsB,
                                                val = required_vals,
                                                sz = required_sz)))
names(x = B) <- c(paste("B", 1:10, sep = "."))

required_subsC <- cbind(rep(x = 1:nrow(input),
                            times = 2),c(input$C,input$C.1))

C <- cbind(as.data.frame(x = pracma::accumarray(subs = required_subsC,
                                                val = required_vals,
                                                sz = required_sz)))
names(x = C) <- c(paste("C", 1:10, sep = "."))

data_final<-cbind(A,B,C)

Here's an attempt to solve your problem. Since you don't describe your problem, I can't visualise it and hence I'm answering based on vague ideas without understanding and leaving huge scope of improvement. May be it's very obvious for people familiar with accumarray, but unfortunately my knowledge is extremely limited.

input_dataset <- data.frame(A = c(1L, 3L, 4L, 6L),
                            A.1 = c(2L, 3L, 7L, 7L),
                            B = c(9L, 10L, 8L, 5L),
                            B.1 = c(9L, 10L, 9L, 6L),
                            C = c(3L, 5L, 7L, 10L),
                            C.1 = c(4L, 6L, 8L, 10L),
                            subject = c("s_1", "s_2", "s_3", "s_4"))

temp_fun <- function(t1, t2)
{
  temp_input_dataset <- input_dataset[startsWith(x = names(x = input_dataset),
                                                 prefix = t2)]
  required_subs <- cbind(rep(x = 1:nrow(temp_input_dataset),
                             times = ncol(x = temp_input_dataset)),
                         stack(x = temp_input_dataset)$values)
  required_vals <- rep(x = 1,
                       times = nrow(x = required_subs))
  required_sz <- c(nrow(x = temp_input_dataset), 10)
  temp_output_dataset <- as.data.frame(x = pracma::accumarray(subs = required_subs,
                                                              val = required_vals,
                                                              sz = required_sz))
  names(x = temp_output_dataset) <- paste(t2, (1:10),
                                          sep = ".")
  cbind(t1, temp_output_dataset)
}

Reduce(f = temp_fun,
       x = c("A", "B", "C"), # in general, supply the vector of variable names here
       init = data.frame(subject = c("s_1", "s_2", "s_3", "s_4")))
#>   subject A.1 A.2 A.3 A.4 A.5 A.6 A.7 A.8 A.9 A.10 B.1 B.2 B.3 B.4 B.5 B.6
#> 1     s_1   1   1   0   0   0   0   0   0   0    0   0   0   0   0   0   0
#> 2     s_2   0   0   2   0   0   0   0   0   0    0   0   0   0   0   0   0
#> 3     s_3   0   0   0   1   0   0   1   0   0    0   0   0   0   0   0   0
#> 4     s_4   0   0   0   0   0   1   1   0   0    0   0   0   0   0   1   1
#>   B.7 B.8 B.9 B.10 C.1 C.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9 C.10
#> 1   0   0   2    0   0   0   1   1   0   0   0   0   0    0
#> 2   0   0   0    2   0   0   0   0   1   1   0   0   0    0
#> 3   0   1   1    0   0   0   0   0   0   0   1   1   0    0
#> 4   0   0   0    0   0   0   0   0   0   0   0   0   0    2

Created on 2019-07-02 by the reprex package (v0.3.0)

Note

Please do not tag in such a extent. You tagged me 3 times from 3 threads on a same question, within a window of around 2 hours!! At least, give me the opportunity to read your post before tagging one more time. I'm sorry if it offends you, but it's not possible for me (and, probably for most of the other people on this community) to be online always. Please familiarise yourself with this thread:

2 Likes

Thank you very much for your help and your constant availability.
It is actually what I was looking for!!
Sorry for the tags, I did it only since I sincerely appreciated your help, I didn't mean to bother you, I'm sorry if it resembled as an inadequate behaviour. Lesson learnt!
Thank you very much once again!

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