R functions: how to return the results correctly

Hello all,

I have updated a completely reproducible example:

  1. the output will be:

    categories 101 102 103 104 105
    X1 140 5.7458361 16.8286002 10.2858604 22.1265875 21.8074200
    X2 150 3.3869650 15.2843799 17.9463137 13.3206970 17.0933358
    X3 140 9.3181736 13.0432330 8.3226908 16.4160228 19.7426646
    X4 150 11.0309918 23.0375231 18.9159073 21.1331776 26.5314855
    X5 140 5.7702094 10.3444563 13.0911201 9.4688664 7.4147125
    X6 150 8.2983155 21.5978890 20.5877644 19.9483565 22.5663474

...

But I want the results to be alined with the control value:

 categories        101        102        103        104        105

X1 140 5.7458361 16.8286002 10.2858604 22.1265875 21.8074200
X2 140 3.3869650 15.2843799 17.9463137 13.3206970 17.0933358
X3 140 9.3181736 13.0432330 8.3226908 16.4160228 19.7426646
X4 140 11.0309918 23.0375231 18.9159073 21.1331776 26.5314855
X5 140 5.7702094 10.3444563 13.0911201 9.4688664 7.4147125
X6 140 8.2983155 21.5978890 20.5877644 19.9483565 22.5663474

...

X1.1 150 5.7458361 16.8286002 10.2858604 22.1265875 21.8074200
X2.1 150 3.3869650 15.2843799 17.9463137 13.3206970 17.0933358
X3.1 150 9.3181736 13.0432330 8.3226908 16.4160228 19.7426646
X4.1 150 11.0309918 23.0375231 18.9159073 21.1331776 26.5314855
X5.1 150 5.7702094 10.3444563 13.0911201 9.4688664 7.4147125
X6.1 150 8.2983155 21.5978890 20.5877644 19.9483565 22.5663474

Is there anyway to improve my codes to achieve correct results?

My second questions is:

if I want the function to return two different results in the same time and save them in seperate data frames, how to achieve it?

Many thanks

library(gsynth)
data(gsynth)
ls()

foo <- function (control_value) {
    new_simdata_sub <- subset (simdata, id <= control_value)
    
    
    out <- gsynth(Y ~ D + X1 + X2, data = simdata, index = c("id","time"), force = "two-way", CV = TRUE, r = c(0, 5), se = TRUE, inference = "parametric", nboots = 1000, parallel = TRUE, cores = 4)
    
    out$Y.ct

}

control_value <- c(140,150)

result <- lapply(control_value, foo)
data.frame(categories = control_value, do.call("rbind", result), check.names = FALSE)

1 Like

Can't say much without a reproducible example, called a reprex. The object whole is missing, for one.

If you want a function to return more than one object, put them in a list and return the list. Then you can get the different bits using the $ operator.

myf <- function(x){
  list(mean=mean(x), median=median(x))
}

x <- myf(c(1,2,3,4,4))
x$mean
x$median

Thanks for reply. I have improved my questions and code. The code used the package's data, thus now everyone can reproduce it.

Thanks. How about if the results are vectors?

The list can contain vectors, data frames or any other type of object. In fact, single values are just vectors of length one.

myf <- function(x){
  list(mean=mean(x), median=median(x), VEC = rep(x, 3), DF = data.frame(Value = x))
}

x <- myf(c(1,2,3,4,4))
x$mean
#> [1] 2.8
x$median
#> [1] 3
x$VEC       
#>  [1] 1 2 3 4 4 1 2 3 4 4 1 2 3 4 4
x$DF
#>   Value
#> 1     1
#> 2     2
#> 3     3
#> 4     4
#> 5     4

Created on 2019-10-31 by the reprex package (v0.2.1)

1 Like

Great! Just add

library(dplyr)
# result of code before last line
sorted_result <- data.frame(categories = control_value, do.call("rbind", result), check.names = FALSE) %>% arrange(categories)

and your data frame will group all the 140s and 150s together, in that order.

Thanks @technocrat. But I think that the order in the categories will change. Is there any way to keep the original order, and also add another indicate variable like 1, 2, 3 ... The results I want are something like this (I didn't type out all the results like 102, ..., 105):

date categories 101 ...
1 140 5.74
2 140 3.39
3 140 9.32
...

Please see the screen, using arange category will change the order.

image