0
votes

I need your help. I have a data frame looks like below

   id      home_1     home_2      home_3
1   1 -0.07288651 -1.0946734  0.06310788
2   2  0.27480575 -0.5939264 -0.10267407
3   3 -1.29267610 -1.0765848 -0.96190129
4   4 -0.53468273  0.5315489 -1.36055340
...

I want to create 3 data frames; df1, df2 and df3

  • df1 would have a table with sorted column 'home_1'
  • df2 would have a table with sorted column 'home_2'
  • df3 would have a table with sorted column 'home_3'

Please find the codes below

dummy <- data.frame(id = 1:10,home_1 = rnorm(10),home_2 = rnorm(10),home_3 = rnorm(10))

f <- function(df,param1, param2) {
    c <- paste0(param1, "_", param2);
    print(paste0("Let's sort column ", c))
    df %>% arrange(c) %>% print()  #sort dataframe by column 'home_1/2/3'
}

for (i in 1:3) {
    print(paste0("Index : ",i))
    table <- paste0("df",i)     
    table <- f(dummy,"home",i) # create dataframe with name df1/2/3
}

Problem 1 Then I run my code, the function cannot detect the respective column. The errors inside my function

Error in grouped_df_impl(data, unname(vars), drop) : 
Column `c` is unknown 

the local variable c does exist, but the group_by function cannot detect c.

Does anybody know how to make Column 'c' to be detected by group_by function?

Problem 2 Same problem with my for loop. I want to create a data frame name that is dynamic.

However, this following function table <- f(dummy,"home",i), created a data frame with name 'table' instead of 'df1'.

Can anybody give me a hint on how to resolve these issues? Thank you in advance.

2
df1<- df[order(df$home_1),] df2<- df[order(df$home_2),] df3<- df[order(df$home_3),] As I suppose, solution such like this won't satisfy you, will it? - Adamm
@Adamm No sir, I want the function to be dynamic. Because I am going to create more than 50+ data frames with the function. - Henry
Ahh sure, so solution by chinsoon12 should do the trick, unless you want each df (sorted already) in separate variable. Afther that lapply() you have list of df's. However you can acces each row and column of df in list by index. - Adamm

2 Answers

1
votes

You can loop through the list of columns and then order by each column

cols <- structure(setdiff(names(dat), "id"), names=setdiff(names(dat), "id"))
lapply(cols, function(x) dat[order(dat[,x]),])

data:

dat <- read.table(text="id      home_1     home_2      home_3
1 -0.07288651 -1.0946734  0.06310788
2  0.27480575 -0.5939264 -0.10267407
3 -1.29267610 -1.0765848 -0.96190129
4 -0.53468273  0.5315489 -1.36055340", header=TRUE)
1
votes

I would use tidyverse's arrange function for this, which is very straight forward.

I'd also use "assign" from base-r to assign a value to a vetor who's name is stored in a string.

library(tidyverse)
for(i in 1:(ncol(dummy)-1)){
  #define the name for the new data
  new = paste0("df",i) 

  #define the same of the column to sort on
  col = paste("home",i,sep="_") 

  # based on the data dummy, arrange the rows according to "col"
  # we need to use "get" because arrange expects bare (unquoted) column names
  tmp = dummy %>% arrange(get(col))
  assign(new, tmp)
 }