Home > Net >  R Function to print columns and rows in tibble - what am I doing wrong?
R Function to print columns and rows in tibble - what am I doing wrong?

Time:05-20

I created a function to print specified blocks of columns and rows of a tibble and it mostly works great. There is one small niggle that I can't figure out. When I have a smaller dataset and want to print all the columns (at specified row ranges), if I specify the number of columns as an argument, nothing prints. However, if I specify one fewer column it prints but split over two sets of rows in the console. I'd like to be able to view all the data on one row in this case.

My function and some test data is below:

# Need to specify:
# 1.Dataframe name
# 2.Number of cols to print in a block
# 3.Start row
# 4.End row
  print_cols <- function(df, ncols, rowstart, rowend) {
    numcols <- length(df)
    i <- 1
    while (i   (ncols-1) < numcols) {
      cat("\n")
      print(paste0("Columns ", i, " to ", (i   (ncols-1)), ": Rows ", rowstart, " to ", rowend))
      print(df[rowstart:rowend, i:(i   (ncols-1))], n = Inf)
      i <- i   ncols
      if (i   (ncols-1) >= numcols) {
        cat("\n")
        print(paste0("Columns ", i, " to ", numcols, ": Rows ", rowstart, " to ", rowend))
        print(df[rowstart:rowend, i:numcols], n = Inf)
      }
    }
  }

# Simulate data and test function
# Print blocks of cols (when many variables)  
dat <- rep(rnorm(50, 50, 20), 100)
dat <- as_tibble(matrix(data = dat, nrow = 50, ncol = 100, byrow = F))
print_cols(dat, 20, 20, 40) # works fine

# Print all columns (when only a few variables)
dat2 <- rep(rnorm(50, 50, 20), 10)
dat2 <- as_tibble(matrix(data = dat2, nrow = 50, ncol = 10, byrow = F))
print_cols(dat2, 10, 20, 40) # prints nothing - WHY??
print_cols(dat2, 9, 20, 40) # need to specify one column less in order to print``` 

CodePudding user response:

Here's how I would rewrite your function:

print_cols = function(df, ncols, rowstart, rowend) {
  if(!is_tibble(df)) {df = as_tibble(df)}
  col_starts = seq(from = 1, to = ncol(df), by = ncols)
  for(i in col_starts) {
    cat("\n")
    if(i < tail(col_starts, 1)) {
      cols = i   0:(ncols - 1) 
    } else { ## last iteration
      cols = i:ncol(df)
    }
    message(sprintf(
        "Columns %s to %s: Rows %s to %s",
        cols[1], tail(cols, 1),
        rowstart, rowend
    ))
    print(df[rowstart:rowend, cols], n = Inf)
  }
}

print_cols(mtcars, 8, 2, 3)
# Columns 1 to 8: Rows 2 to 3
# # A tibble: 2 × 8
#     mpg   cyl  disp    hp  drat    wt  qsec    vs
#   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1  21       6   160   110  3.9   2.88  17.0     0
# 2  22.8     4   108    93  3.85  2.32  18.6     1
# 
# Columns 9 to 11: Rows 2 to 3
# # A tibble: 2 × 3
#      am  gear  carb
#   <dbl> <dbl> <dbl>
# 1     1     4     4
# 2     1     4     1
  • Related