[
  {
    "path": ".Rbuildignore",
    "content": "^.*\\.Rproj$\n^\\.Rproj\\.user$\n^vignettes/introduction_cache$\n^doc$\n^Meta$\n^codecov\\.yml$\n^dev$\n^README_cache$\n^README_files$\nREADME.Rmd\n^.git$\n.coveralls.yml\n.travis.yml\n^.github$\n^\\.github$\n_pkgdown.yml\n^tidyseurat\\.Rproj$\n"
  },
  {
    "path": ".coveralls.yml",
    "content": "service_name: travis-pro\nrepo_token: O4NscPehU4qrWznFtQRiyJJBIOyRgPzsB\n"
  },
  {
    "path": ".github/.gitignore",
    "content": "*.html\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\nThanks for submitting an issue.\n\nPlease add the following information to the issue\n\n1. Describe the issue/bug\n2. Print out the input dataset immediately before the bug occurs\n3. Paste the code immediately leading to the bug\n4. Print out of the output, if any\n5. Print out of the complete error/warning message, if any\n6. sessionInfo()\n\nThanks!\n"
  },
  {
    "path": ".github/workflows/rworkflows.yml",
    "content": "name: rworkflows\n'on':\n  push:\n    branches:\n    - master\n    - main\n    - devel\n    - RELEASE_**\n  pull_request:\n    branches:\n    - master\n    - main\n    - devel\n    - RELEASE_**\njobs:\n  rworkflows:\n    permissions: write-all\n    runs-on: ${{ matrix.config.os }}\n    name: ${{ matrix.config.os }} (${{ matrix.config.r }})\n    container: ${{ matrix.config.cont }}\n    strategy:\n      fail-fast: ${{ false }}\n      matrix:\n        config:\n        - os: ubuntu-latest\n          bioc: devel\n          r: auto\n          cont: ghcr.io/bioconductor/bioconductor_docker:devel\n          rspm: ~\n        - os: macOS-latest\n          bioc: release\n          r: auto\n          cont: ~\n          rspm: ~\n        - os: windows-latest\n          bioc: release\n          r: auto\n          cont: ~\n          rspm: ~\n    steps:\n    - uses: neurogenomics/rworkflows@master\n      with:\n        run_bioccheck: ${{ false }}\n        run_rcmdcheck: ${{ true }}\n        as_cran: ${{ true }}\n        run_vignettes: ${{ true }}\n        has_testthat: ${{ true }}\n        run_covr: ${{ true }}\n        run_pkgdown: ${{ true }}\n        has_runit: ${{ false }}\n        has_latex: ${{ false }}\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        run_docker: ${{ false }}\n        DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}\n        runner_os: ${{ runner.os }}\n        cache_version: cache-v1\n        docker_registry: ghcr.io\n"
  },
  {
    "path": ".gitignore",
    "content": ".Rproj.user\n.Rhistory\n.RData\n.Ruserdata\ntidyseurat.Rproj\nREADME_cache/*\nvignettes/introduction_cache*\ntidyseurat.Rproj\nMeta\ndoc\ndev/*csv\ndev/*rds\ndev/*rda\ndev/*pdf\ndev/dplyr-master/*\ntidyseurat.Rproj\n/doc/\n/Meta/\n..Rcheck/*\n"
  },
  {
    "path": ".travis.yml",
    "content": "# Adapted from https://github.com/hadley/testthat/blob/master/.travis.yml\n# R for travis: see documentation at https://docs.travis-ci.com/user/languages/r\nlanguage: r\ncache: packages\nr:\n - bioc-release\n - bioc-devel\nenv:\n- R_QPDF=true\n\nr_github_packages:\n  - r-lib/covr\n\nafter_success:\n    - tar -C .. -xf $PKG_TARBALL\n    - xvfb-run Rscript -e 'covr::codecov(type=c(\"tests\", \"vignettes\", \"examples\"))'\n"
  },
  {
    "path": "DESCRIPTION",
    "content": "Type: Package\nPackage: tidyseurat\nTitle: Brings Seurat to the Tidyverse \nVersion: 0.8.9\nAuthors@R: c(person(\"Stefano\", \"Mangiola\", email = \"mangiolastefano@gmail.com\",\n                  role = c(\"aut\", \"cre\")),\n            person(\"Maria\", \"Doyle\", email = \"Maria.Doyle@petermac.org\",\n            role = c(\"ctb\"))\n                  )\nDescription: It creates an invisible layer that allow to see the 'Seurat' object \n    as tibble and interact seamlessly with the tidyverse.\nLicense: GPL-3\nDepends:\n    R (>= 4.1.0),\n    ttservice (>= 0.3.8),\n    SeuratObject\nImports:\n    Seurat (>= 4.3.0),\n    tibble,\n    dplyr (>= 1.1.4),\n    magrittr,\n    tidyr (>= 1.2.0),\n    ggplot2,\n    rlang (>= 1.0.0),\n    purrr,\n    lifecycle,\n    methods,\n    plotly,\n    tidyselect,\n    utils,\n    vctrs,\n    pillar,\n    stringr,\n    cli,\n    fansi,\n    Matrix,\n    generics\nSuggests:\n    testthat,\n    knitr,\n    GGally,\n    markdown,\n    rbibutils\nVignetteBuilder: \n    knitr\nRdMacros:\n    lifecycle\nBiarch: true\nbiocViews: AssayDomain, Infrastructure, RNASeq, DifferentialExpression, GeneExpression, Normalization, Clustering, QualityControl, Sequencing, Transcription, Transcriptomics\nEncoding: UTF-8\nLazyData: true\nRoxygenNote: 7.3.3\nURL: https://github.com/stemangiola/tidyseurat, https://stemangiola.github.io/tidyseurat/\nBugReports: https://github.com/stemangiola/tidyseurat/issues\n"
  },
  {
    "path": "NAMESPACE",
    "content": "# Generated by roxygen2: do not edit by hand\n\nS3method(add_count,Seurat)\nS3method(add_count,default)\nS3method(arrange,Seurat)\nS3method(as_tibble,Seurat)\nS3method(bind_cols,Seurat)\nS3method(bind_rows,Seurat)\nS3method(count,Seurat)\nS3method(distinct,Seurat)\nS3method(extract,Seurat)\nS3method(filter,Seurat)\nS3method(full_join,Seurat)\nS3method(ggplot,Seurat)\nS3method(glimpse,tidyseurat)\nS3method(group_by,Seurat)\nS3method(group_split,Seurat)\nS3method(inner_join,Seurat)\nS3method(join_transcripts,Seurat)\nS3method(join_transcripts,default)\nS3method(left_join,Seurat)\nS3method(mutate,Seurat)\nS3method(nest,Seurat)\nS3method(pivot_longer,Seurat)\nS3method(plot_ly,Seurat)\nS3method(plot_ly,tbl_df)\nS3method(print,Seurat)\nS3method(pull,Seurat)\nS3method(rename,Seurat)\nS3method(right_join,Seurat)\nS3method(rowwise,Seurat)\nS3method(sample_frac,Seurat)\nS3method(sample_n,Seurat)\nS3method(select,Seurat)\nS3method(separate,Seurat)\nS3method(slice,Seurat)\nS3method(slice_head,Seurat)\nS3method(slice_max,Seurat)\nS3method(slice_min,Seurat)\nS3method(slice_sample,Seurat)\nS3method(slice_tail,Seurat)\nS3method(summarise,Seurat)\nS3method(summarize,Seurat)\nS3method(tbl_format_header,tidySeurat)\nS3method(tidy,Seurat)\nS3method(unite,Seurat)\nS3method(unnest,tidyseurat_nested)\nexport(\"%>%\")\nexport(add_count)\nexport(get_abundance_sc_long)\nexport(get_abundance_sc_wide)\nexport(join_transcripts)\nexport(plot_ly)\nexport(unnest_seurat)\nexportMethods(join_features)\nimportFrom(Matrix,rowSums)\nimportFrom(Seurat,Assays)\nimportFrom(Seurat,DietSeurat)\nimportFrom(Seurat,GetAssayData)\nimportFrom(Seurat,SplitObject)\nimportFrom(Seurat,VariableFeatures)\nimportFrom(SeuratObject,\"DefaultAssay<-\")\nimportFrom(SeuratObject,DefaultAssay)\nimportFrom(dplyr,arrange)\nimportFrom(dplyr,contains)\nimportFrom(dplyr,count)\nimportFrom(dplyr,distinct)\nimportFrom(dplyr,distinct_at)\nimportFrom(dplyr,everything)\nimportFrom(dplyr,filter)\nimportFrom(dplyr,full_join)\nimportFrom(dplyr,group_by)\nimportFrom(dplyr,group_by_drop_default)\nimportFrom(dplyr,group_rows)\nimportFrom(dplyr,group_split)\nimportFrom(dplyr,inner_join)\nimportFrom(dplyr,left_join)\nimportFrom(dplyr,mutate)\nimportFrom(dplyr,pull)\nimportFrom(dplyr,rename)\nimportFrom(dplyr,right_join)\nimportFrom(dplyr,rowwise)\nimportFrom(dplyr,sample_frac)\nimportFrom(dplyr,sample_n)\nimportFrom(dplyr,select)\nimportFrom(dplyr,select_if)\nimportFrom(dplyr,slice)\nimportFrom(dplyr,slice_head)\nimportFrom(dplyr,slice_max)\nimportFrom(dplyr,slice_min)\nimportFrom(dplyr,slice_sample)\nimportFrom(dplyr,slice_tail)\nimportFrom(dplyr,summarise)\nimportFrom(dplyr,summarize)\nimportFrom(dplyr,vars)\nimportFrom(fansi,strwrap_ctl)\nimportFrom(generics,tidy)\nimportFrom(ggplot2,aes)\nimportFrom(ggplot2,ggplot)\nimportFrom(lifecycle,deprecate_warn)\nimportFrom(magrittr,\"%$%\")\nimportFrom(magrittr,\"%>%\")\nimportFrom(magrittr,equals)\nimportFrom(methods,.hasSlot)\nimportFrom(methods,getMethod)\nimportFrom(methods,is)\nimportFrom(pillar,align)\nimportFrom(pillar,get_extent)\nimportFrom(pillar,style_subtle)\nimportFrom(pillar,tbl_format_header)\nimportFrom(plotly,plot_ly)\nimportFrom(purrr,imap)\nimportFrom(purrr,map)\nimportFrom(purrr,map2)\nimportFrom(purrr,map_chr)\nimportFrom(purrr,map_int)\nimportFrom(purrr,reduce)\nimportFrom(purrr,when)\nimportFrom(rlang,\":=\")\nimportFrom(rlang,check_dots_used)\nimportFrom(rlang,dots_values)\nimportFrom(rlang,enexpr)\nimportFrom(rlang,enquo)\nimportFrom(rlang,enquos)\nimportFrom(rlang,expr)\nimportFrom(rlang,flatten_if)\nimportFrom(rlang,is_spliced)\nimportFrom(rlang,names2)\nimportFrom(rlang,quo_name)\nimportFrom(rlang,quo_squash)\nimportFrom(rlang,sym)\nimportFrom(stats,setNames)\nimportFrom(stringr,regex)\nimportFrom(stringr,str_detect)\nimportFrom(tibble,as_tibble)\nimportFrom(tibble,column_to_rownames)\nimportFrom(tibble,enframe)\nimportFrom(tibble,glimpse)\nimportFrom(tibble,rowid_to_column)\nimportFrom(tidyr,extract)\nimportFrom(tidyr,nest)\nimportFrom(tidyr,pivot_longer)\nimportFrom(tidyr,separate)\nimportFrom(tidyr,spread)\nimportFrom(tidyr,unite)\nimportFrom(tidyr,unnest)\nimportFrom(tidyselect,eval_select)\nimportFrom(ttservice,aggregate_cells)\nimportFrom(ttservice,bind_cols)\nimportFrom(ttservice,bind_rows)\nimportFrom(ttservice,join_features)\nimportFrom(utils,packageDescription)\nimportFrom(utils,tail)\nimportFrom(vctrs,new_data_frame)\n"
  },
  {
    "path": "R/attach.R",
    "content": "core <- c(\"dplyr\", \"tidyr\", \"ttservice\", \"ggplot2\")\n\ncore_unloaded <- function() {\n    search <- paste0(\"package:\", core)\n    core[!search %in% search()]\n}\n\n# Attach the package from the same library it was loaded from before.\n# [source: https://github.com/tidy-biology/tidyverse/issues/171]\nsame_library <- function(pkg) {\n    loc <- if (pkg %in% loadedNamespaces()) \n        dirname(getNamespaceInfo(pkg, \"path\"))\n    library(pkg, lib.loc=loc, character.only=TRUE, warn.conflicts=FALSE)\n}\n\ntidyverse_attach <- function() {\n    to_load <- core_unloaded()\n    \n    suppressPackageStartupMessages(\n        lapply(to_load, same_library))\n    \n    invisible(to_load)\n}\n"
  },
  {
    "path": "R/data.R",
    "content": "#' Cell types of 80 PBMC single cells\n#' \n#' A dataset containing the barcodes and cell types of 80 PBMC single cells.\n#'\n#' @format A tibble containing 80 rows and 2 columns.\n#'   Cells are a subsample of the Peripheral Blood Mononuclear Cells (PBMC) \n#'   dataset of 2,700 single cell. Cell types were identified with SingleR.\n#' \\describe{\n#'   \\item{cell}{cell identifier, barcode}\n#'   \\item{first.labels}{cell type}\n#' }\n#' @source \\url{https://satijalab.org/seurat/v3.1/pbmc3k_tutorial.html}\n#' @usage data(cell_type_df)\n#' @return `tibble`\n\"cell_type_df\"\n\n#' Intercellular ligand-receptor interactions for \n#' 38 ligands from a single cell RNA-seq cluster.\n#'\n#' A dataset containing ligand-receptor interactions within a sample.\n#' There are 38 ligands from a single cell cluster versus 35 receptors \n#' in 6 other clusters.\n#'\n#' @format A `tibble` containing 100 rows and 9 columns.\n#'   Cells are a subsample of the PBMC dataset of 2,700 single cells. \n#'   Cell interactions were identified with `SingleCellSignalR`.\n#' \\describe{\n#'   \\item{sample}{sample identifier}\n#'   \\item{ligand}{cluster and ligand identifier}\n#'   \\item{receptor}{cluster and receptor identifier}\n#'   \\item{ligand.name}{ligand name}\n#'   \\item{receptor.name}{receptor name}\n#'   \\item{origin}{cluster containing ligand}\n#'   \\item{destination}{cluster containing receptor}\n#'   \\item{interaction.type}{type of interation, paracrine or autocrine}\n#'   \\item{LRscore}{interaction score}\n#' }\n#' @source \\url{https://satijalab.org/seurat/v3.1/pbmc3k_tutorial.html}\n#' @usage data(pbmc_small_nested_interactions)\n#' @return `tibble`\n\"pbmc_small_nested_interactions\""
  },
  {
    "path": "R/dplyr_methods.R",
    "content": "#' @name arrange\n#' @rdname arrange\n#' @inherit dplyr::arrange\n#' @family single table verbs\n#'\n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |>\n#'     arrange(nFeature_RNA)\n#' \n#' @importFrom tibble as_tibble\n#' @importFrom dplyr arrange\n#' @export\narrange.Seurat <- function(.data, ..., .by_group=FALSE) {\n  \n  # DEPRECATE\n  deprecate_warn(\n    when=\"0.7.5\",\n    what=\"arrange()\",\n    details=\"tidyseurat says: arrange() is temporarly deprected as it is not clear that Seurat allows reordering of cells.\"\n  )\n  \n    # .cell_ordered <-\n    #     .data %>%\n    #     as_tibble() %>%\n    #     dplyr::arrange(  ..., .by_group=.by_group  ) %>%\n    #    pull(!!c_(.data)$symbol)\n    # \n    # .data[,.cell_ordered]\n  \n  .data\n}\n\n#' @name bind_rows\n#' @rdname bind_rows\n#' @inherit ttservice::bind_rows\n#'\n#' @examples\n#' data(pbmc_small)\n#' tt <- pbmc_small\n#' ttservice::bind_rows(tt, tt)\n#'\n#' tt_bind <- tt |> select(nCount_RNA ,nFeature_RNA)\n#' tt |> ttservice::bind_cols(tt_bind)\n#' \n#' @importFrom rlang dots_values\n#' @importFrom rlang flatten_if\n#' @importFrom rlang is_spliced\n#' @importFrom ttservice bind_rows\n#' @export\nbind_rows.Seurat <- function(..., .id=NULL,  add.cell.ids=NULL)\n{\n    tts <- flatten_if(dots_values(...), is_spliced)\n\n    # Strange error for Seurat merge\n    # GetResidualSCTModel\n    # close to a line as such\n    # slot(object=object[[assay]], name=\"SCTModel.list\")\n    # So I have to delete any sample of size 1 if I have calculated SCT\n    # if()\n    # GetAssayData(object, layer='SCTModel.list', assay=\"SCT\") %>%\n    #     map(~ .x@cell.attributes %>% nrow)\n\n    # Check if cell with same name\n    merge(tts[[1]], y=tts[[2]], add.cell.ids=add.cell.ids)\n}\n\n#' @importFrom rlang flatten_if\n#' @importFrom rlang is_spliced\n#' @importFrom rlang dots_values\n#' @importFrom ttservice bind_cols\nbind_cols_ <- function(..., .id=NULL){\n\n    tts <- flatten_if(dots_values(...), is_spliced)\n\n    tts[[1]]@meta.data <- bind_cols(tts[[1]][[]], tts[[2]], .id=.id)\n\n    tts[[1]]\n}\n\n#' @rdname bind_rows\n#' @aliases bind_cols\n#' @export\nbind_cols.Seurat <- bind_cols_\n\n#' @name distinct\n#' @rdname distinct\n#' @inherit dplyr::distinct\n#'\n#' @examples\n#' data(\"pbmc_small\")\n#' pbmc_small |> distinct(groups)\n#'\n#' @importFrom dplyr distinct\n#' @export\ndistinct.Seurat <- function (.data, ..., .keep_all=FALSE)\n{\n    message(data_frame_returned_message)\n\n    distinct_columns <-\n        (enquos(..., .ignore_empty=\"all\") %>% map(~ quo_name(.x)) %>% unlist)\n\n    # Deprecation of special column names\n    if(is_sample_feature_deprecated_used(.data, distinct_columns)){\n        .data= ping_old_special_column_into_metadata(.data)\n    }\n\n    .data %>%\n        as_tibble() %>%\n        dplyr::distinct(..., .keep_all=.keep_all)\n\n}\n\n#' @name filter\n#' @rdname filter\n#' @inherit dplyr::filter\n#' \n#' @examples\n#' data(\"pbmc_small\")\n#' pbmc_small |>  filter(groups == \"g1\")\n#'\n#' # Learn more in ?dplyr_eval\n#' \n#' @importFrom purrr map\n#' @importFrom dplyr filter\n#' @export\nfilter.Seurat <- function (.data, ..., .preserve=FALSE)\n{\n\n    # Deprecation of special column names\n    if(is_sample_feature_deprecated_used(\n        .data,\n        (enquos(..., .ignore_empty=\"all\") %>% map(~ quo_name(.x)) %>% unlist)\n    )){\n        .data= ping_old_special_column_into_metadata(.data)\n    }\n\n    new_meta <- .data %>%\n        as_tibble() %>%\n        dplyr::filter( ..., .preserve=.preserve) %>%\n        as_meta_data(.data)\n\n    # Error if size == 0\n    if(nrow(new_meta) == 0) stop(\"tidyseurat says: the resulting data\",\n        \" container is empty. Seurat does not allow for empty containers.\")\n\n    new_obj <-\n        subset(.data, cells=rownames(new_meta)) %>%\n\n    # Clean empty slots\n    clean_seurat_object()\n\n    new_obj\n\n}\n\n#' @name group_by\n#' @rdname group_by\n#' @inherit dplyr::group_by\n#' \n#' @examples\n#' data(\"pbmc_small\")\n#' pbmc_small |>  group_by(groups)\n#'\n#' @importFrom dplyr group_by_drop_default\n#' @importFrom dplyr group_by\n#' @export\ngroup_by.Seurat <- function (.data, ..., .add=FALSE,\n    .drop=group_by_drop_default(.data))\n{\n    message(data_frame_returned_message)\n\n    # Deprecation of special column names\n    if(is_sample_feature_deprecated_used(\n        .data,\n        (enquos(..., .ignore_empty=\"all\") %>% map(~ quo_name(.x)) %>% unlist)\n    )){\n        .data <- ping_old_special_column_into_metadata(.data)\n    }\n\n    .data %>%\n        as_tibble() %>%\n        dplyr::group_by( ..., .add=.add, .drop=.drop)\n\n}\n\n#' @name summarise\n#' @aliases summarize\n#' @inherit dplyr::summarise\n#' @family single table verbs\n#' \n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> summarise(mean(nCount_RNA))\n#'\n#' @importFrom dplyr summarise\n#' @importFrom purrr map\n#' @export\nsummarise.Seurat <- function (.data, ...) {\n    message(data_frame_returned_message)\n\n    # Deprecation of special column names\n    if(is_sample_feature_deprecated_used(\n        .data,\n        (enquos(..., .ignore_empty=\"all\") %>% map(~ quo_name(.x)) %>% unlist)\n    )){\n        .data= ping_old_special_column_into_metadata(.data)\n    }\n\n    .data %>%\n        as_tibble() %>%\n        dplyr::summarise( ...)\n\n}\n\n#' @name summarise\n#' @rdname summarise\n#' @importFrom dplyr summarize\n#' @export\nsummarize.Seurat <- summarise.Seurat\n\n#' @name mutate\n#' @rdname mutate\n#' @inherit dplyr::mutate\n#' @family single table verbs\n#'\n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> mutate(nFeature_RNA=1)\n#'\n#' @importFrom rlang enquos\n#' @importFrom dplyr mutate\n#' @importFrom purrr map\n#' @export\nmutate.Seurat <- function(.data, ...) {\n\n    # Check that we are not modifying a key column\n    cols <- enquos(...) %>% names\n\n    # Deprecation of special column names\n    .cols <- enquos(..., .ignore_empty=\"all\") %>% \n        map(~ quo_name(.x)) %>% unlist()\n    if (is_sample_feature_deprecated_used(.data, .cols)) {\n        .data <- ping_old_special_column_into_metadata(.data)\n    }\n\n    .view_only_cols <- c(\n        get_special_columns(.data),\n        get_needed_columns(.data))\n    \n    .test <- cols |>\n        intersect(.view_only_cols) |>\n        length()\n\n    if (.test) {\n        stop(\"tidyseurat says:\",\n            \" you are trying to mutate a column that is view only\",\n            \" \", paste(.view_only_cols, collapse=\", \"),\n            \" (it is not present in the colData).\",\n            \" If you want to mutate a view-only column, make a copy\",\n            \" (e.g. mutate(new_column=\", cols[1], \")) and mutate that one.\")\n    }\n\n    .data@meta.data <-\n        .data %>%\n        as_tibble %>%\n        dplyr::mutate( ...)  %>%\n        as_meta_data(.data)\n\n    .data\n}\n\n#' @name rename\n#' @rdname rename\n#' @inherit dplyr::rename\n#' @family single table verbs\n#'\n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> rename(s_score=nFeature_RNA)\n#'\n#' @importFrom Seurat DietSeurat\n#' @importFrom tidyselect eval_select\n#' @importFrom dplyr rename\n#' @export\nrename.Seurat <- function(.data, ...)\n{\n\n    # Check that we are not modifying a key column\n    read_only_columns <- c(\n        get_needed_columns(.data),\n        get_special_columns(.data))\n\n    # Small df to be more efficient\n    df <- \n      DietSeurat(.data, features = rownames(.data)[1])[,1]  |>\n      suppressWarnings() |> \n      as_tibble() \n    \n    # What columns we are going to create\n    cols_from <- tidyselect::eval_select(expr(c(...)), df) |> names()\n    \n    # What are the columns before renaming\n    original_columns <- df |> colnames()\n    \n    # What the column after renaming would be\n    new_colums <- df |> rename(...) |> colnames()\n    \n    # What column you are impacting\n    changed_columns <- original_columns |> setdiff(new_colums)\n    \n    # Check that you are not impacting any read-only columns\n    if (any(changed_columns %in% read_only_columns)) {\n        stop(\"tidyseurat says:\",\n            \" you are trying to rename a column that is view only\",\n            \" \", paste(changed_columns, collapse=\", \"),\n            \" (it is not present in the colData).\",\n            \" If you want to rename a view-only column, make a copy\",\n            \" (e.g., mutate(\", cols_from[1], \"=\",  changed_columns[1], \")).\")\n    }\n\n    .data@meta.data <- dplyr::rename( .data[[]],  ...)\n\n    .data\n}\n\n#' @name rowwise\n#' @rdname rowwise\n#' @inherit dplyr::rowwise\n#'\n#' @examples\n#' # TODO\n#'\n#' @importFrom dplyr rowwise\n#' @export\nrowwise.Seurat <- function(data, ...) {\n    message(data_frame_returned_message)\n\n    data %>%\n        as_tibble() %>%\n        dplyr::rowwise(...)\n\n}\n\n#' @name left_join\n#' @rdname left_join\n#' @inherit dplyr::left_join\n#'\n#' @examples\n#' data(pbmc_small)\n#' tt <- pbmc_small\n#' tt |> left_join(tt |>  \n#'   distinct(groups) |> \n#'   mutate(new_column=1:2))\n#'\n#' @importFrom dplyr left_join\n#' @importFrom dplyr count\n#' @export\nleft_join.Seurat <- function (x, y, by=NULL, copy=FALSE,\n    suffix=c(\".x\", \".y\"), ...) {\n\n    # Deprecation of special column names\n    .cols <- if (!is.null(by)) by else colnames(y)\n    if (is_sample_feature_deprecated_used(x, .cols)) {\n        x <- ping_old_special_column_into_metadata(x)\n    }\n\n    x %>%\n        as_tibble() %>%\n        dplyr::left_join( y, by=by, copy=copy, suffix=suffix, ...) %>%\n\n        when(\n\n            # If duplicated cells returns tibble\n            count(., !!c_(x)$symbol) %>% filter(n>1) %>% nrow %>% gt(0) ~ {\n                message(duplicated_cell_names)\n                (.)\n            },\n\n            # Otherwise return updated tidyseurat\n            ~ {\n                x@meta.data <- (.) %>% as_meta_data(x)\n                x\n            }\n        )\n\n}\n\n#' @name inner_join\n#' @rdname inner_join\n#' @inherit dplyr::inner_join\n#'\n#' @examples\n#' data(pbmc_small)\n#' tt <- pbmc_small\n#' tt |> inner_join(tt |> \n#'   distinct(groups) |>  \n#'   mutate(new_column=1:2) |> \n#'   slice(1))\n#'\n#' @importFrom dplyr inner_join\n#' @importFrom dplyr pull\n#' @export\ninner_join.Seurat <- function (x, y, by=NULL, copy=FALSE,\n    suffix=c(\".x\", \".y\"), ...) {\n\n    # Deprecation of special column names\n    .cols <- if (!is.null(by)) by else colnames(y)\n    if (is_sample_feature_deprecated_used(x, .cols)) {\n        x <- ping_old_special_column_into_metadata(x)\n    }\n\n    x %>%\n        as_tibble() %>%\n        dplyr::inner_join( y, by=by, copy=copy, suffix=suffix, ...)  %>%\n\n        when(\n\n            # If duplicated cells returns tibble\n            count(., !!c_(x)$symbol) %>% filter(n>1) %>% nrow %>% gt(0) ~ {\n                message(duplicated_cell_names)\n                (.)\n            },\n\n            # Otherwise return updated tidyseurat\n            ~ {\n                new_obj <- subset(x, cells= pull(., c_(x)$name))\n                new_obj@meta.data <- (.) %>% as_meta_data(new_obj)\n                new_obj\n            }\n        )\n\n}\n\n#' @name right_join\n#' @rdname right_join\n#' @inherit dplyr::right_join\n#'\n#' @examples\n#' data(pbmc_small)\n#' tt <- pbmc_small\n#' tt |> right_join(tt |> \n#'   distinct(groups) |> \n#'   mutate(new_column=1:2) |> \n#'   slice(1))\n#'\n#' @importFrom dplyr right_join\n#' @importFrom dplyr pull\n#' @export\nright_join.Seurat <- function (x, y, by=NULL, copy=FALSE,\n    suffix=c(\".x\", \".y\"), ...) {\n\n    # Deprecation of special column names\n    .cols <- if (!is.null(by)) by else colnames(y)\n    if (is_sample_feature_deprecated_used(x, .cols)) {\n        x <- ping_old_special_column_into_metadata(x)\n    }\n\n    x %>%\n        as_tibble() %>%\n        dplyr::right_join( y, by=by, copy=copy, suffix=suffix, ...) %>%\n\n        when(\n\n            # If duplicated cells returns tibble\n            count(., !!c_(x)$symbol) %>% filter(n>1) %>% nrow %>% gt(0) ~ {\n                message(duplicated_cell_names)\n                (.)\n            },\n\n            # Otherwise return updated tidyseurat\n            ~ {\n                new_obj <- subset(x, cells=(.) %>% pull(c_(x)$name))\n                new_obj@meta.data <- (.) %>% as_meta_data(new_obj)\n                new_obj\n            }\n        )\n\n}\n\n#' @name full_join\n#' @rdname full_join\n#' @inherit dplyr::full_join\n#'\n#' @examples\n#' data(pbmc_small)\n#' tt <- pbmc_small\n#' tt |> full_join(tibble::tibble(groups=\"g1\", other=1:4))\n#'\n#' @importFrom dplyr full_join\n#' @export\nfull_join.Seurat <- function (x, y, by=NULL, copy=FALSE,\n    suffix=c(\".x\", \".y\"), ...) {\n\n    # Deprecation of special column names\n    .cols <- if (!is.null(by)) by else colnames(y)\n    if (is_sample_feature_deprecated_used(x, .cols)) {\n        x <- ping_old_special_column_into_metadata(x)\n    }\n\n    x %>%\n        as_tibble() %>%\n        dplyr::full_join( y, by=by, copy=copy, suffix=suffix, ...) %>%\n\n        when(\n\n            # If duplicated cells returns tibble\n            count(., !!c_(x)$symbol) %>% filter(n>1) %>% nrow %>% gt(0) ~ {\n                message(duplicated_cell_names)\n                (.)\n            },\n\n            # Otherwise return updated tidyseurat\n            ~ {\n                x@meta.data <- (.) %>% as_meta_data(x)\n                x\n            }\n        )\n\n}\n\n#' @name slice\n#' @rdname slice\n#' @aliases slice_head slice_tail \n#'   slice_sample slice_min slice_max\n#' @inherit dplyr::slice\n#' @family single table verbs\n#' \n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> slice(1)\n#' \n#' # Slice group-wise using .by\n#' pbmc_small |> slice(1:2, .by=groups)\n#'\n#' @importFrom dplyr slice\n#' @importFrom tibble rowid_to_column\n#' @export\nslice.Seurat <- function (.data, ..., .by=NULL, .preserve=FALSE)\n{\n    row_number___ <- NULL\n    idx <- .data[[]] |>\n        select(-everything(), {{ .by }}) |>\n        rowid_to_column(var='row_number___')  |>\n        slice(..., .by={{ .by }}, .preserve=.preserve) |>\n        pull(row_number___)\n\n    if (length(idx) == 0) {\n        stop(\"tidyseurat says: the resulting data container is empty.\",\n            \" Seurat does not allow for empty containers.\")\n    }\n\n    new_obj <- subset(.data,   cells=colnames(.data)[idx])\n    new_obj\n}\n\n#' @name slice_sample\n#' @rdname slice\n#' @inherit dplyr::slice_sample\n#' @examples\n#'\n#' # slice_sample() allows you to random select with or without replacement\n#' pbmc_small |> slice_sample(n=5)\n#'\n#' # if using replacement, and duplicate cells are returned, a tibble will be\n#' # returned because duplicate cells cannot exist in Seurat objects\n#' pbmc_small |> slice_sample(n=1, replace=TRUE) # returns Seurat\n#' pbmc_small |> slice_sample(n=100, replace=TRUE) # returns tibble\n#'\n#' # weight by a variable\n#' pbmc_small |> slice_sample(n=5, weight_by=nCount_RNA)\n#'\n#' # sample by group\n#' pbmc_small |> slice_sample(n=5, by=groups)\n#'\n#' # sample using proportions\n#' pbmc_small |> slice_sample(prop=0.10)\n#'\n#' @importFrom dplyr slice_sample\n#' @export\nslice_sample.Seurat <- function(.data, ..., n=NULL,\n    prop=NULL, by=NULL, weight_by=NULL, replace=FALSE) {\n\n    # Solve CRAN NOTES\n    cell <- NULL\n    . <- NULL\n\n    lifecycle::signal_superseded(\"1.0.0\", \"sample_n()\", \"slice_sample()\")\n\n    if (!is.null(n))\n        new_meta <-\n            .data[[]] |>\n            as_tibble(rownames=c_(.data)$name) |>\n            select(-everything(), c_(.data)$name, {{ by }}, {{ weight_by }}) |>\n            slice_sample(..., n=n, by={{ by }},\n                weight_by={{ weight_by }}, replace=replace)\n    else if (!is.null(prop))\n        new_meta <-\n            .data[[]] |>\n            as_tibble(rownames=c_(.data)$name) |>\n            select(-everything(), c_(.data)$name, {{ by }}, {{ weight_by }}) |>\n            slice_sample(..., prop=prop, by={{ by }},\n                weight_by={{ weight_by }}, replace=replace)\n    else\n        stop(\"tidyseurat says: you should provide `n` or `prop` arguments\")\n\n    count_cells <- new_meta %>%\n        select(!!c_(.data)$symbol) %>%\n        count(!!c_(.data)$symbol)\n    .max_cell_count <- ifelse(nrow(count_cells)==0, 0, max(count_cells$n))\n\n    # If repeated cells due to replacement\n    if (.max_cell_count |> gt(1)){\n        message(\"tidyseurat says: When sampling with replacement\",\n            \" a data frame is returned for independent data analysis.\")\n        .data |>\n            as_tibble()  |>\n            right_join(new_meta %>% \n                select(!!c_(.data)$symbol), by=c_(.data)$name)\n    } else {\n        new_obj <- subset(.data, cells=new_meta %>% pull(!!c_(.data)$symbol))\n        new_obj\n    }\n}\n\n#' @name slice_head\n#' @rdname slice\n#' @inherit dplyr::slice_head\n#' @examples\n#'\n#' # First rows based on existing order\n#' pbmc_small |> slice_head(n=5)\n#' \n#' @importFrom dplyr slice_head\n#' @importFrom tibble rowid_to_column\n#' @export\nslice_head.Seurat <- function(.data, ..., n, prop, by=NULL) {\n    row_number___ <- NULL\n    idx <- .data[[]] |>\n        select(-everything(), {{ by }}) |>\n        rowid_to_column(var='row_number___')  |>\n        slice_head(..., n=n, prop=prop, by={{ by }}) |>\n        pull(row_number___)\n\n    if (length(idx) == 0) {\n        stop(\"tidyseurat says: the resulting data container is empty.\",\n            \" Seurat does not allow for empty containers.\")\n    }\n    new_obj <- subset(.data, cells=colnames(.data)[idx])\n    new_obj\n}\n\n#' @name slice_tail\n#' @rdname slice\n#' @inherit dplyr::slice_tail\n#' @examples\n#'\n#' # Last rows based on existing order\n#' pbmc_small |> slice_tail(n=5)\n#' \n#' @importFrom dplyr slice_tail\n#' @importFrom tibble rowid_to_column\n#' @export\nslice_tail.Seurat <- function(.data, ..., n, prop, by=NULL) {\n    row_number___ <- NULL\n    idx <- .data[[]] |>\n        select(-everything(), {{ by }}) |>\n        rowid_to_column(var='row_number___')  |>\n        slice_tail(..., n=n, prop=prop, by={{ by }}) |>\n        pull(row_number___)\n\n    if (length(idx) == 0) {\n        stop(\"tidyseurat says: the resulting data container is empty.\",\n            \" Seurat does not allow for empty containers.\")\n    }\n\n    new_obj <- subset(.data, cells=colnames(.data)[idx])\n    new_obj\n}\n\n#' @name slice_min\n#' @rdname slice\n#' @inherit dplyr::slice_min\n#' @examples\n#'\n#' # Rows with minimum and maximum values of a metadata variable\n#' pbmc_small |> slice_min(nFeature_RNA, n=5)\n#'\n#' # slice_min() and slice_max() may return more rows than requested\n#' # in the presence of ties.\n#' pbmc_small |>  slice_min(nFeature_RNA, n=2)\n#'\n#' # Use with_ties=FALSE to return exactly n matches\n#' pbmc_small |> slice_min(nFeature_RNA, n=2, with_ties=FALSE)\n#'\n#' # Or use additional variables to break the tie:\n#' pbmc_small |> slice_min(tibble::tibble(nFeature_RNA, nCount_RNA), n=2)\n#'\n#' # Use by for group-wise operations\n#' pbmc_small |> slice_min(nFeature_RNA, n=5, by=groups)\n#'\n#' @importFrom dplyr slice_min\n#' @importFrom tibble rowid_to_column\n#' @export\nslice_min.Seurat <- function(.data, order_by, ..., n, prop,\n    by=NULL, with_ties=TRUE, na_rm=FALSE) {\n    row_number___ <- NULL\n    order_by_variables <- return_arguments_of(!!enexpr(order_by))\n\n    idx <- .data[[]] |>\n        select(-everything(), !!!order_by_variables, {{ by }}) |>\n        rowid_to_column(var ='row_number___')  |>\n        slice_min(\n            order_by={{ order_by }}, ..., n=n, prop=prop, by={{ by }},\n            with_ties=with_ties, na_rm=na_rm\n        ) |>\n        pull(row_number___)\n\n    if (length(idx) == 0) {\n        stop(\"tidyseurat says: the resulting data container is empty.\",\n            \" Seurat does not allow for empty containers.\")\n    }\n\n    new_obj <- subset(.data, cells=colnames(.data)[idx])\n    new_obj\n}\n\n#' @name slice_max\n#' @rdname slice\n#' @inherit dplyr::slice_max\n#' @examples\n#'\n#' # Rows with minimum and maximum values of a metadata variable\n#' pbmc_small |> slice_max(nFeature_RNA, n=5)\n#' \n#' @importFrom dplyr slice_max\n#' @importFrom tibble rowid_to_column\n#' @export\nslice_max.Seurat <- function(.data, order_by, ..., n, prop,\n    by=NULL, with_ties=TRUE, na_rm=FALSE) {\n    row_number___ <- NULL\n\n    order_by_variables <- return_arguments_of(!!enexpr(order_by))\n\n    idx <- .data[[]] |>\n        select(-everything(), !!!order_by_variables, {{ by }}) |>\n        rowid_to_column(var ='row_number___')  |>\n        slice_max(\n            order_by={{ order_by }}, ..., n=n, prop=prop, by={{ by }},\n            with_ties=with_ties, na_rm=na_rm\n        ) |>\n        pull(row_number___)\n\n    if (length(idx) == 0) {\n        stop(\"tidyseurat says: the resulting data container is empty.\",\n            \" Seurat does not allow for empty containers.\")\n    }\n\n    new_obj <- subset(.data, cells=colnames(.data)[idx])\n    new_obj\n}\n\n#' @name select\n#' @rdname select\n#' @inherit dplyr::select\n#'\n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> select(cell, orig.ident)\n#' \n#' @importFrom dplyr select\n#' @export\nselect.Seurat <- function (.data, ...)\n{\n    # Deprecation of special column names\n    .cols <- enquos(..., .ignore_empty=\"all\") %>% \n        map(~ quo_name(.x)) %>% unlist()\n    if (is_sample_feature_deprecated_used(.data, .cols)) {\n        .data <- ping_old_special_column_into_metadata(.data)\n    }\n\n    .data %>%\n        as_tibble() %>%\n        select_helper(...) %>%\n        when(\n\n            # If key columns are missing\n            (get_needed_columns(.data) %in% colnames(.)) %>% all %>% `!` ~ {\n                message(\"tidyseurat says: Key columns are missing.\",\n                    \" A data frame is returned for independent data analysis.\")\n                (.)\n            },\n\n            # If valid seurat meta data\n            ~ {\n                .data@meta.data <- (.) %>% as_meta_data(.data)\n                .data\n            }\n        )\n\n}\n\n#' @name sample_n\n#' @rdname sample_n\n#' @aliases sample_frac\n#' @inherit dplyr::sample_n\n#' \n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> sample_n(50)\n#' pbmc_small |> sample_frac(0.1)\n#' \n#' @importFrom dplyr sample_n\n#' @export\nsample_n.Seurat <- function(tbl, size, replace=FALSE,\n                                weight=NULL, .env=NULL, ...) {\n    # Solve CRAN NOTES\n    cell <- NULL\n    . <- NULL\n\n    lifecycle::signal_superseded(\"1.0.0\", \"sample_n()\", \"slice_sample()\")\n\n    new_meta <- tbl[[]] %>%\n        as_tibble(rownames=c_(tbl)$name) %>%\n        dplyr::sample_n(size, replace=replace, weight=weight, .env=.env, ...)\n\n    count_cells <- new_meta %>%\n        select(!!c_(tbl)$symbol) %>%\n        count(!!c_(tbl)$symbol)\n\n    # If repeted cells\n    if (count_cells$n %>% max() %>% gt(1)){\n        message(\"tidyseurat says: When sampling with replacement\",\n            \" a data frame is returned for independent data analysis.\")\n        tbl %>%\n            as_tibble() %>%\n            right_join(new_meta %>% select(!!c_(tbl)$symbol),  by=c_(tbl)$name)\n    } else {\n        new_obj <- subset(tbl, cells=new_meta %>% pull(!!c_(tbl)$symbol))\n        new_obj@meta.data <-\n            new_meta %>%\n            data.frame(row.names=pull(.,!!c_(tbl)$symbol),\n                check.names=FALSE) %>%\n            select(- !!c_(tbl)$symbol)\n        new_obj\n    }\n}\n\n#' @rdname sample_n\n#' @importFrom dplyr sample_frac\n#' @export\nsample_frac.Seurat <- function(tbl, size=1, replace=FALSE,\n                                   weight=NULL, .env=NULL, ...) {\n\n    # Solve CRAN NOTES\n    cell <- NULL\n    . <- NULL\n\n    lifecycle::signal_superseded(\"1.0.0\", \"sample_frac()\", \"slice_sample()\")\n\n    new_meta <- tbl[[]] %>% \n        as_tibble(rownames=c_(tbl)$name) %>%\n        dplyr::sample_frac(size, replace=replace,\n            weight=weight, .env=.env, ...)\n\n    count_cells <- new_meta %>%\n        select(!!c_(tbl)$symbol) %>%\n        count(!!c_(tbl)$symbol)\n\n    # If repeted cells\n    if (count_cells$n %>% max() %>% gt(1)){\n        message(\"tidyseurat says: When sampling with replacement\",\n            \" a data frame is returned for independent data analysis.\")\n        tbl %>%\n            as_tibble() %>%\n            right_join(new_meta %>% select(!!c_(tbl)$symbol),  by=c_(tbl)$name)\n    } else {\n        new_obj <- subset(tbl, cells=new_meta %>% pull(!!c_(tbl)$symbol))\n        new_obj@meta.data <-\n            new_meta %>%\n            data.frame(row.names=pull(.,!!c_(tbl)$symbol),\n                check.names=FALSE) %>%\n            select(- !!c_(tbl)$symbol)\n        new_obj\n    }\n}\n\n#' Count observations by group\n#'\n#' @description\n#' `count()` lets you quickly count the unique values of one or more variables:\n#' `df %>% count(a, b)` is roughly equivalent to\n#' `df %>% group_by(a, b) %>% summarise(n = n())`.\n#' `count()` is paired with `tally()`, a lower-level helper that is equivalent\n#' to `df %>% summarise(n = n())`. Supply `wt` to perform weighted counts,\n#' switching the summary from `n = n()` to `n = sum(wt)`.\n#'\n#' `add_count()` and `add_tally()` are equivalents to `count()` and `tally()`\n#' but use `mutate()` instead of `summarise()` so that they add a new column\n#' with group-wise counts.\n#'\n#' @param x A data frame, data frame extension (e.g. a tibble), or a\n#'   lazy data frame (e.g. from dbplyr or dtplyr).\n#' @param ... <[`data-masking`][dplyr_data_masking]> Variables to group by.\n#' @param wt <[`data-masking`][dplyr_data_masking]> Frequency weights.\n#'   Can be `NULL` or a variable:\n#'\n#'   * If `NULL` (the default), counts the number of rows in each group.\n#'   * If a variable, computes `sum(wt)` for each group.\n#' @param sort If `TRUE`, will show the largest groups at the top.\n#' @param name The name of the new column in the output.\n#'\n#'   If omitted, it will default to `n`. If there's already a column called `n`,\n#'   it will error, and require you to specify the name.\n#' @param .drop For `count()`: if `FALSE` will include counts for empty groups\n#'   (i.e. for levels of factors that don't exist in the data).\n#' @return\n#' An object of the same type as `.data`. `count()` and `add_count()`\n#' group transiently, so the output has the same groups as the input.\n#' @name count\n#' @rdname count\n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> count(groups)\n#'     \n#' @importFrom dplyr count\n#' @export\ncount.Seurat <- function(x, ..., wt=NULL, sort=FALSE,\n    name=NULL, .drop=group_by_drop_default(x)) {\n\n    message(\"tidyseurat says: A data frame is\",\n        \" returned for independent data analysis.\")\n\n    # Deprecation of special column names\n    .cols <- enquos(..., .ignore_empty=\"all\") %>% \n        map(~ quo_name(.x)) %>% unlist()\n    if (is_sample_feature_deprecated_used(x, .cols)) {\n        x <- ping_old_special_column_into_metadata(x)\n    }\n\n    x %>%\n        as_tibble() %>%\n        dplyr::count(..., wt=!!enquo(wt), sort=sort, name=name, .drop=.drop)\n}\n\n#' @export\n#' @rdname count\nadd_count <- function(x, ..., wt=NULL, sort=FALSE, name=NULL) {\n    UseMethod(\"add_count\")\n}\n\n#' @export\n#' @rdname count\nadd_count.default <- function(x, ..., wt=NULL, sort=FALSE, name=NULL) {\n    if (is.null(name)) name <- \"n\"\n    .out <- x %>%\n        dplyr::group_by(..., .add = TRUE) %>%\n        dplyr::mutate(!!rlang::sym(name) := if (is.null(wt)) dplyr::n() else sum(!!enquo(wt), na.rm = TRUE)) %>%\n        dplyr::ungroup()\n    if (sort) .out <- dplyr::arrange(.out, dplyr::desc(!!rlang::sym(name)))\n    .out\n}\n\n#' @rdname count\n#' @aliases add_count\n#' @importFrom rlang sym\n#' @export\nadd_count.Seurat <- function(x, ..., wt=NULL, sort=FALSE, name=NULL) {\n\n    # Deprecation of special column names\n    .cols <- enquos(..., .ignore_empty=\"all\") %>%\n        map(~ quo_name(.x)) %>% unlist()\n    if (is_sample_feature_deprecated_used(x, .cols)) {\n        x <- ping_old_special_column_into_metadata(x)\n    }\n\n    if (is.null(name)) name <- \"n\"\n    .out <- x %>%\n        as_tibble %>%\n        dplyr::group_by(..., .add = TRUE) %>%\n        dplyr::mutate(!!sym(name) := if (is.null(wt)) dplyr::n() else sum(!!enquo(wt), na.rm = TRUE)) %>%\n        dplyr::ungroup()\n    if (sort) .out <- dplyr::arrange(.out, dplyr::desc(!!sym(name)))\n    x@meta.data <- .out %>% as_meta_data(x)\n\n    x\n}\n\n#' @name pull\n#' @rdname pull\n#' @inherit dplyr::pull\n#' \n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> pull(groups)\n#' \n#' @importFrom dplyr pull\n#' @export\npull.Seurat <- function(.data, var=-1, name=NULL, ...) {\n    var <- enquo(var)\n    name <- enquo(name)\n\n    message(\"tidyseurat says: A data frame is\",\n        \" returned for independent data analysis.\")\n\n    # Deprecation of special column names\n    if(is_sample_feature_deprecated_used(\n        .data,\n        quo_name(var)\n    )){\n        .data <- ping_old_special_column_into_metadata(.data)\n    }\n\n    .data %>%\n        as_tibble() %>%\n        dplyr::pull( var=!!var, name=!!name, ...)\n}\n\n#' @name group_split\n#' @rdname group_split\n#' @inherit dplyr::group_split\n#' \n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> group_split(groups)\n#' \n#' @importFrom rlang check_dots_used\n#' @importFrom dplyr group_by\n#' @importFrom dplyr group_rows\n#' @importFrom dplyr group_split\n#' @export\ngroup_split.Seurat <- function(.tbl, ..., .keep = TRUE) {\n  \n  var_list <- enquos(...)\n  \n  group_list <- .tbl |> \n    as_tibble() |> \n    dplyr::group_by(!!!var_list)\n  \n  groups <- group_list |> \n    dplyr::group_rows()\n  \n  v <- vector(mode = \"list\", length = length(groups))\n  \n  for (i in seq_along(v)) {\n    v[[i]] <- .tbl[,groups[[i]]]\n    \n    if(.keep == FALSE) {\n      v[[i]] <- select(v[[i]], !(!!!var_list))\n    }\n  }\n  \n  v\n  \n}\n"
  },
  {
    "path": "R/ggplot2_methods.R",
    "content": "#' @name ggplot\n#' @rdname ggplot\n#' @inherit ggplot2::ggplot\n#' @title Create a new \\code{ggplot} from a \\code{tidyseurat}\n#' @return `ggplot`\n#'\n#' @examples\n#' library(ggplot2)\n#' data(pbmc_small)\n#' pbmc_small |> \n#'   ggplot(aes(groups, nCount_RNA)) +\n#'   geom_boxplot()\n#' \n#' @importFrom purrr map\n#' @importFrom rlang quo_name\n#' @importFrom ggplot2 aes ggplot\n#' @export\nggplot.Seurat <- function(data=NULL, mapping=aes(),\n    ..., environment=parent.frame()) {\n  \n    # Deprecation of special column names\n    .cols <- mapping %>% \n        unlist() %>% map(~ quo_name(.x)) %>% \n        unlist() %>% as.character()\n    if (is_sample_feature_deprecated_used(data, .cols)) {\n        data <- ping_old_special_column_into_metadata(data)\n    }\n  \n    data %>%\n        as_tibble() %>%\n        ggplot2::ggplot(mapping=mapping)\n}\n"
  },
  {
    "path": "R/methods.R",
    "content": "#' @importFrom methods getMethod\nsetMethod(\n    f=\"show\",\n    signature=\"Seurat\",\n    definition=function(object) {\n        if (isTRUE(x=getOption(x=\"restore_Seurat_show\", default=FALSE))) {\n            f <- getMethod(\n                f=\"show\",\n                signature=\"Seurat\",\n                where=asNamespace(ns=\"SeuratObject\"))\n            f(object=object)\n        } else { print(object) }\n    }\n)\n\nsetClass(\"tidyseurat\", contains=\"Seurat\")\n\n#' @importFrom generics tidy\n\n#' @title tidy for Seurat objects\n#' @name tidy\n#' @description tidy for Seurat objects\n#' @param x A Seurat object\n#' @param ... Additional arguments (not used)\n#' @return A tidyseurat object\n#' @importFrom lifecycle deprecate_warn\n#' @export\ntidy.Seurat <- function(x, ...){ \n  \n    # DEPRECATE\n    deprecate_warn(\n        when=\"0.2.0\",\n        what=\"tidy()\",\n        details=\"tidyseurat says: tidy() is not needed anymore.\"\n    )\n  \n    return(x)\n}\n\n\n\n#' @name join_features\n#' @rdname join_features\n#' @inherit ttservice::join_features\n#' @aliases join_features,Seurat-method\n#'\n#' @param .data A tidyseurat object\n#' @param assay assay name to extract feature abundance\n#' @param slot slot name to extract feature abundance\n#' \n#' @return A `tidyseurat` object\n#'   containing information for the specified features.\n#'\n#' @examples\n#' data(pbmc_small)\n#' pbmc_small %>% join_features(\n#'   features=c(\"HLA-DRA\", \"LYZ\"))\n#'\n#' @importFrom magrittr \"%>%\"\n#' @importFrom dplyr contains\n#' @importFrom dplyr everything\n#' @importFrom ttservice join_features\n#' @export\nsetMethod(\"join_features\", \"Seurat\", function(.data,\n    features=NULL, all=FALSE, exclude_zeros=FALSE, shape=\"wide\",\n    assay=NULL, slot=\"data\", ...) {\n  \n  .feature = NULL\n  \n  if(shape == \"long\")\n    .data |> \n    left_join(\n      get_abundance_sc_long(\n        .data=.data,\n        features=features,\n        all=all,\n        exclude_zeros=exclude_zeros,\n        assay=assay,\n        slot=slot,\n        ...\n      ),\n      by=c_(.data)$name\n    ) %>%\n    select(!!c_(.data)$symbol, .feature,\n           contains(\".abundance\"), everything())\n  else\n    .data |> \n    left_join(\n      get_abundance_sc_wide(\n        .data=.data,\n        features=features,\n        all=all,\n        assay=assay,\n        slot=slot,\n        ...\n      ),\n      by=c_(.data)$name\n    ) \n\n})\n\n#' @name aggregate_cells\n#' @rdname aggregate_cells\n#' @inherit ttservice::aggregate_cells\n#' @aliases aggregate_cells,Seurat-method\n#' \n#' @param .data A tidyseurat object\n#' \n#' @examples \n#' data(pbmc_small)\n#' pbmc_small_pseudo_bulk <- pbmc_small |>\n#'   aggregate_cells(c(groups, letter.idents), assays=\"RNA\")\n#'\n#' @importFrom rlang enquo\n#' @importFrom magrittr \"%>%\"\n#' @importFrom tibble enframe\n#' @importFrom Matrix rowSums\n#' @importFrom ttservice aggregate_cells\n#' @importFrom SeuratObject DefaultAssay\n#' @importFrom Seurat DietSeurat\n#' @importFrom Seurat GetAssayData\n#' @importFrom purrr map_int\nsetMethod(\"aggregate_cells\", \"Seurat\",  function(.data,\n    .sample=NULL, slot=\"data\", assays=NULL,\n    aggregation_function=Matrix::rowSums, ...){\n    # Solve NOTE  \n    data <- NULL\n    .feature <- NULL\n  \n    .sample <- enquo(.sample)\n\n    # Subset only wanted assays\n    if(!is.null(assays)){\n        DefaultAssay(.data) <- assays[1]\n        .data = .data |> DietSeurat(assays = assays)\n    }\n\n    .data %>%\n        nest(data=-!!.sample) %>%\n        mutate(.aggregated_cells=map_int(data, ~ ncol(.x))) %>% \n        mutate(\n            data=map(data, ~ \n                # Loop over assays\n                map2(.x@assays, names(.x@assays),\n                    # Get counts\n                    ~ GetAssayData_robust(.x, layer=slot) %>%\n                        aggregation_function(na.rm=T) %>%\n                        tibble::enframe(\n                            name=\".feature\",\n                            value=sprintf(\"%s\", .y)\n                        ) %>%\n                        mutate(.feature=as.character(.feature)) \n                ) %>%\n                Reduce(function(...) full_join(..., by=c(\".feature\")), .), \n                .progress = TRUE          \n        )) %>%\n        left_join(\n            .data %>%\n                as_tibble() %>%\n                subset_tidyseurat(!!.sample)) %>%\n        unnest(data) %>%\n        tidyr::unite(\".sample\", !!.sample,  sep=\"___\", remove=FALSE) |> \n        select(.feature, .sample, names(.data@assays), everything()) |> \n        drop_class(\"tidyseurat_nested\") \n})"
  },
  {
    "path": "R/methods_DEPRECATED.R",
    "content": "#' (DEPRECATED) Extract and join information for transcripts.\n#'\n#'\n#' @description join_transcripts() extracts and joins information for specified transcripts\n#'\n#' @importFrom rlang enquo\n#' @importFrom magrittr \"%>%\"\n#'\n#' @name join_transcripts\n#' @rdname join_transcripts\n#'\n#' @param .data A tidyseurat object\n#' @param transcripts A vector of transcript identifiers to join\n#' @param all If TRUE return all\n#' @param exclude_zeros If TRUE exclude zero values\n#' @param shape Format of the returned table \"long\" or \"wide\"\n#' @param ... Parameters to pass to join wide, i.e. assay name to extract transcript abundance from\n#'\n#' @details DEPRECATED, please use join_features()\n#'\n#' @return A `tbl` containing the information.for the specified transcripts\n#' \n#' @examples\n#'\n#' print(\"DEPRECATED\")\n#'\n#'\n#' @export\n#'\njoin_transcripts <- function(.data,\n                          transcripts = NULL,\n                          all = FALSE,\n                          exclude_zeros = FALSE,\n                          shape = \"wide\", ...) {\n  UseMethod(\"join_transcripts\", .data)\n}\n#' @export\njoin_transcripts.default <-\n  function(.data,\n           transcripts = NULL,\n           all = FALSE,\n           exclude_zeros = FALSE,\n           shape = \"wide\", ...)\n  {\n    print(\"tidyseurat says: This function cannot be applied to this object\")\n  }\n#' @export\njoin_transcripts.Seurat <-\n  function(.data,\n           transcripts = NULL,\n           all = FALSE,\n           exclude_zeros = FALSE,\n           shape = \"wide\", ...)\n  {\n    \n    deprecate_warn(\"0.2.1\", \"join_transcripts()\", \"tidyseurat::join_features()\")\n    \n    \n    .data %>%\n      join_features(features = transcripts,\n                       all = all,\n                       exclude_zeros = exclude_zeros,\n                       shape = shape, ...)\n    \n  }"
  },
  {
    "path": "R/pillar_utilities.R",
    "content": "NBSP <- \"\\U00A0\"\n\npillar___format_comment <- function (x, width)\n{\n    if (length(x) == 0L) {\n        return(character())\n    }\n    map_chr(x, pillar___wrap, prefix=\"# \",\n        width=min(width, cli::console_width()))\n}\n\n#' @importFrom fansi strwrap_ctl\npillar___strwrap2 <- function (x, width, indent)\n{\n    fansi::strwrap_ctl(x, width=max(width, 0),\n        indent=indent, exdent=indent + 2)\n}\n\n\npillar___wrap <- function (..., indent=0, prefix=\"\", width)\n{\n    x <- paste0(..., collapse=\"\")\n    wrapped <- pillar___strwrap2(x, width - get_extent(prefix), indent)\n    wrapped <- paste0(prefix, wrapped)\n    wrapped <- gsub(NBSP, \" \", wrapped)\n    paste0(wrapped, collapse=\"\\n\")\n}\n"
  },
  {
    "path": "R/plotly_methods.R",
    "content": "#' @name plotly\n#' @rdname plotly\n#' @inherit plotly::plot_ly\n#' @return `plotly`\n#' \n#' @examples\n#' data(pbmc_small)\n#' plot_ly(pbmc_small)\n#' \n#' @importFrom plotly plot_ly\n#' @export\nplot_ly <- function(data=data.frame(), ..., type=NULL, name=NULL,\n    color=NULL, colors=NULL, alpha=NULL,\n    stroke=NULL, strokes=NULL, alpha_stroke=1,\n    size=NULL, sizes=c(10, 100),\n    span=NULL, spans=c(1, 20),\n    symbol=NULL, symbols=NULL,\n    linetype=NULL, linetypes=NULL,\n    split=NULL, frame=NULL,\n    width=NULL, height=NULL, source=\"A\") {\n    UseMethod(\"plot_ly\")\n}\n\n#' @rdname plotly\n#' @export\nplot_ly.tbl_df <- function(data=data.frame(), ..., type=NULL, name=NULL,\n    color=NULL, colors=NULL, alpha=NULL,\n    stroke=NULL, strokes=NULL, alpha_stroke=1,\n    size=NULL, sizes=c(10, 100),\n    span=NULL, spans=c(1, 20),\n    symbol=NULL, symbols=NULL,\n    linetype=NULL, linetypes=NULL,\n    split=NULL, frame=NULL,\n    width=NULL, height=NULL, source=\"A\") {\n    data %>%\n        # This is a trick to not loop the call\n        drop_class(\"tbl_df\") %>%\n        plotly::plot_ly(...,\n            type=type, name=name,\n            color=color, colors=colors, alpha=alpha,\n            stroke=stroke, strokes=strokes, alpha_stroke=alpha_stroke,\n            size=size, sizes=sizes,\n            span=span, spans=spans,\n            symbol=symbol, symbols=symbols,\n            linetype=linetype, linetypes=linetypes,\n            split=split, frame=frame,\n            width=width, height=height, source=source)\n}\n\n#' @rdname plotly\n#' @export\nplot_ly.Seurat <- function(data=data.frame(), ..., type=NULL, name=NULL,\n    color=NULL, colors=NULL, alpha=NULL, \n    stroke=NULL, strokes=NULL, alpha_stroke=1,\n    size=NULL, sizes=c(10, 100), \n    span=NULL, spans=c(1, 20),\n    symbol=NULL, symbols=NULL,\n    linetype=NULL, linetypes=NULL,\n    split=NULL, frame=NULL, \n    width=NULL, height=NULL, source=\"A\") {\n  \n    data %>%\n        # This is a trick to not loop the call\n        as_tibble() %>%\n        plot_ly(..., type=type, name=name,\n\t        color=color, colors=colors, alpha=alpha, \n\t        stroke=stroke, strokes=strokes, alpha_stroke=alpha_stroke,\n\t        size=size, sizes=sizes, \n\t        span=span, spans=spans,\n\t        symbol=symbol, symbols=symbols, \n\t        linetype=linetype, linetypes=linetypes,\n\t        split=split, frame=frame, \n\t        width=width, height=height, source=source)    \n}\n"
  },
  {
    "path": "R/print_method.R",
    "content": "# This file is a replacement of the unexported functions in the tibble\n# package, in order to specify \"tibble abstraction in the header\"\n\n#' @name tbl_format_header\n#' @rdname tbl_format_header\n#' @inherit pillar::tbl_format_header\n#' \n#' @examples\n#' # TODO\n#' \n#' @importFrom rlang names2\n#' @importFrom pillar align\n#' @importFrom pillar get_extent\n#' @importFrom pillar style_subtle\n#' @importFrom pillar tbl_format_header\n#' @export\ntbl_format_header.tidySeurat <- function(x, setup, ...){\n  \n    number_of_features <- x |> attr(\"number_of_features\")\n    assay_names <- x |> attr(\"assay_names\")\n    active_assay <- x |> attr(\"active_assay\")\n  \n    named_header <- setup$tbl_sum\n  \n    # Change name\n    names(named_header) <- \"A Seurat-tibble abstraction\"\n  \n    if (all(names2(named_header) == \"\")) {\n        header <- named_header\n    } else {\n        header <- paste0(\n        align(paste0(names2(named_header), \":\"), space=NBSP),\n        \" \", named_header) %>%\n        # Add further info single-cell\n        append(sprintf(\n            \"\\033[90m Features=%s | Cells=%s | Active assay=%s | Assays=%s\\033[39m\",\n            number_of_features,\n            nrow(x),\n            active_assay,\n            assay_names %>% paste(collapse=\", \")\n        ), after=1)\n    }\n    style_subtle(pillar___format_comment(header, width=setup$width))\n}\n\n\n#' @name formatting\n#' @rdname formatting\n#' @aliases print\n#' @inherit tibble::formatting\n#' @return Prints a message to the console describing\n#'   the contents of the `tidyseurat`.\n#'\n#' @param ... Passed on to \\code{\\link[pillar:tbl_format_setup]{tbl_format_setup()}}.\n#' @param n_extra Number of extra columns to print abbreviated information for,\n#'   if the width is too small for the entire tibble. If `NULL`, the default,\n#'   will print information about at most `tibble.max_extra_cols` extra columns.\n#' @examples\n#' data(pbmc_small)\n#' print(pbmc_small)\n#' \n#' @importFrom vctrs new_data_frame\n#' @importFrom Seurat GetAssayData\n#' @importFrom Seurat Assays\n#' @export\nprint.Seurat <- function(x, ..., n=NULL, width=NULL, n_extra=NULL) {\n\n    x |>\n        as_tibble(n_dimensions_to_return=5) |>\n        new_data_frame(class=c(\"tidySeurat\", \"tbl\")) %>%\n        add_attr(GetAssayData(x) %>% nrow,  \"number_of_features\") %>%\n        add_attr(Assays(x) , \"assay_names\") %>%\n        add_attr(x@active.assay , \"active_assay\") %>%\n        print()\n    invisible(x)\n}\n\n"
  },
  {
    "path": "R/tibble_methods.R",
    "content": "#' @name as_tibble\n#' @rdname as_tibble\n#' @inherit tibble::as_tibble\n#' @return `tibble`\n#' \n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> as_tibble()\n#' \n#' @importFrom tibble as_tibble\n#' @importFrom purrr reduce\n#' @importFrom purrr map\n#' @importFrom tidyr spread\n#' @importFrom tibble enframe\n#' @export\nas_tibble.Seurat <- function(x, ...,\n    .name_repair=c(\"check_unique\", \"unique\", \"universal\", \"minimal\"),\n    rownames=NULL){\n\n    x[[]] %>%\n        tibble::as_tibble(rownames=c_(x)$name) %>%\n\n        # Attach reduced dimensions\n        when(\n            # Only if I have reduced dimensions and special datasets\n            length(x@reductions) > 0 ~ (.) %>%\n                left_join(\n                    get_special_datasets(x, ...) %>%\n                    map(~ .x %>% when(\n                        # If row == 1 do a trick\n                        dim(.) %>% is.null ~ {\n                            (.) %>% tibble::enframe() %>%\n                                spread(name, value) %>%\n                                mutate(!!c_(x)$symbol := rownames(x[[]]))\n                        },\n\n                        # Otherwise continue normally\n                        ~ as_tibble(., rownames=c_(x)$name)\n                    )) %>%\n                    reduce(left_join, by=c_(x)$name),\n                by=c_(x)$name\n                ),\n            # Otherwise skip\n            ~ (.)\n        )\n}\n\n#' @name glimpse\n#' @rdname glimpse\n#' @inherit pillar::glimpse\n#'\n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> glimpse()\n#' \n#' @importFrom tibble glimpse\n#' @export\nglimpse.tidyseurat <- function(x, width=NULL, ...){\n    x %>%\n        as_tibble() %>%\n        tibble::glimpse(width=width, ...)\n}\n"
  },
  {
    "path": "R/tidyr_methods.R",
    "content": "#' @name unnest\n#' @rdname unnest\n#' @inherit tidyr::unnest\n#' @aliases unnest_seurat\n#' @return `tidyseurat`\n#' \n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> \n#'     nest(data=-groups) |> \n#'     unnest(data)\n#'\n#' @importFrom rlang quo_name\n#' @importFrom purrr imap\n#' @importFrom tidyr unnest\n#' @export\nunnest.tidyseurat_nested <- function(data, cols, ...,\n    keep_empty=FALSE, ptype=NULL, names_sep=NULL, \n    names_repair=\"check_unique\", .drop, .id, .sep, .preserve) {\n\n    cols <- enquo(cols)\n\n    unnest_seurat(data, !!cols, ...,\n        keep_empty=keep_empty, ptype=ptype,\n        names_sep=names_sep, names_repair=names_repair)\n\n}\n\n#' @rdname unnest\n#' @importFrom tidyr unnest\n#' @importFrom purrr when\n#' @importFrom rlang quo_name\n#' @importFrom purrr imap\n#' @export\nunnest_seurat  <-  function(data, cols, ...,\n    keep_empty=FALSE, ptype=NULL,\n    names_sep=NULL, names_repair=\"check_unique\",\n    .drop, .id, .sep, .preserve) {\n    # Need this otherwise crashes map\n    .data_ <- data\n  \n    cols <- enquo(cols)\n  \n    .data_ %>% \n        when(\n      \n            # If my only column to unnest is tidyseurat\n            pull(., !!cols) %>% .[[1]] %>% is(\"Seurat\") %>% any ~  \n            {\n                # Do my trick to unnest\n                list_seurat <- mutate(.,\n                    !!cols := imap(\n                        !!cols, ~ .x %>%\n                            bind_cols_(\n                                .data_ %>%\n                                    select(-!!cols) %>%\n                                    slice(rep(.y, nrow(as_tibble(.x))))\n                            )\n                        )) %>%\n                    pull(!!cols)\n                list_seurat[[1]] %>%\n                    # Bind only if length list > 1\n                    when(\n                        length(list_seurat)>1 ~ bind_rows(.,\n                            list_seurat[2:length(list_seurat)]),\n                        ~ (.)\n                    )\n            },\n      \n            # Else do normal stuff\n            ~ (.) %>% \n                drop_class(\"tidyseurat_nested\") %>%\n                tidyr::unnest(!!cols, ..., keep_empty=keep_empty,\n                    ptype=ptype, names_sep=names_sep,\n                    names_repair=names_repair) %>%\n                add_class(\"tidyseurat_nested\"))\n}\n\n\n#' @name nest\n#' @rdname nest\n#' @inherit tidyr::nest\n#' @return `tidyseurat_nested`\n#'\n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> \n#'     nest(data=-groups) |> \n#'     unnest(data)\n#' \n#' @importFrom tidyr nest\n#' @importFrom magrittr equals\n#' @importFrom rlang enquos\n#' @importFrom Seurat SplitObject\n#' @importFrom Seurat DietSeurat\n#' @importFrom rlang :=\n#' @export\nnest.Seurat <- function (.data, ..., .names_sep=NULL)\n{\n    cols <- enquos(...)\n    col_name_data  <- names(cols)\n\n    # Deprecation of special column names\n    .cols <- enquos(..., .ignore_empty=\"all\") %>%\n        map(~ quo_name(.x)) %>% unlist()\n    if (is_sample_feature_deprecated_used(.data, .cols)) {\n        .data <- ping_old_special_column_into_metadata(.data)\n    }\n  \n    my_data__ <- .data \n  \n    # This is for getting the column names\n    dummy_nested <- \n        my_data__ |> \n        DietSeurat(features = rownames(my_data__)[1:2], assays = DefaultAssay(my_data__)) |>\n        suppressWarnings() |> \n        to_tib() %>%\n        tidyr::nest(...)\n  \n    split_by_column <- \n        dummy_nested |> \n        select(-col_name_data) |>\n        colnames()\n  \n    # If nesting on one group use the fast split\n    if (split_by_column |> length() |> identical(1L))\n  \n        my_data__ |> \n            SplitObject(split.by=split_by_column) |>\n            map(~ .x |> select(-split_by_column)) |> \n            enframe(name=split_by_column, value=col_name_data) |>\n            # Coerce to tidyseurat_nested for unnesting\n            add_class(\"tidyseurat_nested\")\n  \n    # If arbitrary nest is needed use the slow one\n    else\n        my_data__ %>%\n        # This is needed otherwise nest goes into loop and fails\n            to_tib %>%\n            tidyr::nest(...) %>%\n      \n            mutate(\n                !!as.symbol(col_name_data) := map(\n                    !!as.symbol(col_name_data),\n                    ~ my_data__ %>% \n                    # Subset cells\n                    filter(!!c_(.data)$symbol %in% \n                        pull(.x, !!c_(.data)$symbol)) %>%\n                    # Subset columns\n                    select(colnames(.x))\n                )) |>\n      \n            # Coerce to tidyseurat_nested for unnesting\n            add_class(\"tidyseurat_nested\")\n}\n\n#' @name extract\n#' @rdname extract\n#' @inherit tidyr::extract\n#' @return `tidyseurat`\n#' \n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |>\n#'   extract(groups, \n#'     into=\"g\", \n#'     regex=\"g([0-9])\", \n#'     convert=TRUE)\n#' \n#' @importFrom tidyr extract\n#' @export\nextract.Seurat <- function  (data, col, into,\n    regex=\"([[:alnum:]]+)\", remove=TRUE, convert=FALSE, ...) {\n\t\n    col <- enquo(col)\n\t\n\t# Deprecation of special column names\n\tif (is_sample_feature_deprecated_used(\n\t    data, \n\t    c(quo_name(col), into)\n\t)) {\n\t    data= ping_old_special_column_into_metadata(data)\n\t}\n\t\n\tdata@meta.data <- \n\t    data %>%\n\t    as_tibble() %>%\n\t    tidyr::extract(col=!!col, into=into, regex=regex,\n            remove=remove, convert=convert, ...) %>%\n\t    as_meta_data(data)\n\n\tdata\n}\n\n#' @name pivot_longer\n#' @rdname pivot_longer\n#' @inherit tidyr::pivot_longer\n#' @return `tidyseurat`\n#' \n#' @export\n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> pivot_longer(\n#'   cols=c(orig.ident, groups),\n#'   names_to=\"name\", values_to=\"value\")\n#' \n#' @importFrom rlang check_dots_used\n#' @importFrom tidyr pivot_longer\n#' @export\npivot_longer.Seurat <- function(data,\n    cols, names_to=\"name\", names_prefix=NULL,\n    names_sep=NULL, names_pattern=NULL, names_ptypes=NULL,\n    names_transform=NULL, names_repair=\"check_unique\",\n    values_to=\"value\", values_drop_na=FALSE,\n    values_ptypes=NULL, values_transform=NULL, ...) {\n    cols <- enquo(cols) \n  \n    message(data_frame_returned_message)\n  \n    # Deprecation of special column names\n    if (is_sample_feature_deprecated_used(\n        data, \n        c(quo_names(cols))\n    )) {\n        data= ping_old_special_column_into_metadata(data)\n    }\n  \n    data %>%\n        as_tibble() %>%\n        tidyr::pivot_longer(!!cols, names_to=names_to,\n            names_prefix=names_prefix, names_sep=names_sep,\n            names_pattern=names_pattern, names_ptypes=names_ptypes,\n            names_transform=names_transform, names_repair=names_repair,\n            values_to=values_to, values_drop_na=values_drop_na,\n            values_ptypes=values_ptypes, values_transform=values_transform,\n            ...)\n}\n\n#' @name unite\n#' @rdname unite\n#' @inherit tidyr::unite\n#' @return `tidyseurat`\n#' \n#' @examples\n#' data(pbmc_small)\n#' pbmc_small |> unite(\n#'   col=\"new_col\", \n#'   c(\"orig.ident\", \"groups\"))\n#'     \n#' @importFrom rlang enquo enquos quo_name\n#' @importFrom tidyr unite\n#' @export\nunite.Seurat <- function(data, col,\n    ..., sep=\"_\", remove=TRUE, na.rm=FALSE) {\n  \n    # Check that we are not modifying a key column\n    cols <- enquo(col) \n  \n    # Deprecation of special column names\n    .cols <- enquos(..., .ignore_empty=\"all\") %>% \n        map(~ quo_name(.x)) %>% unlist()\n    if (is_sample_feature_deprecated_used(data, .cols)) {\n        data <- ping_old_special_column_into_metadata(data)\n    }\n\n    .view_only_cols <- c(\n        get_special_columns(data),\n        get_needed_columns(data))\n    \n    .test <- intersect(\n        quo_names(cols), \n        .view_only_cols)\n\n    if (remove && length(.test)) {\n        stop(\"tidyseurat says:\",\n            \" you are trying to rename a column\",\n            \" that is view only \", \n            paste(.view_only_cols, collapse=\", \"),\n            \" (it is not present in the colData).\",\n            \" If you want to mutate a view-only column,\",\n            \" make a copy and mutate that one.\")\n    }\n  \n    data@meta.data <- data %>%\n        as_tibble() %>%\n        tidyr::unite(!!cols, ..., sep=sep,\n            remove=remove, na.rm=na.rm) %>%\n        as_meta_data(data)\n  \n    data\n}\n\n#' @name separate\n#' @rdname separate\n#' @inherit tidyr::separate\n#' @return `tidyseurat`\n#' \n#' @examples\n#' data(pbmc_small)\n#' un <- pbmc_small |> unite(\"new_col\", c(orig.ident, groups))\n#' un |> separate(new_col, c(\"orig.ident\", \"groups\"))\n#' \n#' @importFrom tidyr separate\n#' @export\nseparate.Seurat <- function(data, col, into,\n    sep=\"[^[:alnum:]]+\", remove=TRUE, convert=FALSE,\n    extra=\"warn\", fill=\"warn\", ...) {\n  \n    # Check that we are not modifying a key column\n    cols <- enquo(col)\n  \n    # Deprecation of special column names\n    if(is_sample_feature_deprecated_used(\n        data, \n        c(quo_names(cols))\n    )) {\n        data= ping_old_special_column_into_metadata(data)\n    }\n\n    .view_only_cols <- c(\n        get_special_columns(data),\n        get_needed_columns(data))\n    \n    .test <- intersect(\n        quo_names(cols), \n        .view_only_cols)\n\n    if (remove && length(.test)) {\n        stop(\"tidyseurat says:\",\n            \" you are trying to rename a column\",\n            \" that is view only \",\n            paste(.view_only_cols, collapse=\", \"),\n            \"(it is not present in the colData).\",\n            \" If you want to mutate a view-only column,\",\n            \" make a copy and mutate that one.\")\n    }\n   \n    data@meta.data =\n        data %>%\n        as_tibble() %>% \n        tidyr::separate(!!cols, into=into, sep=sep, remove=remove, \n            convert=convert, extra=extra, fill=fill, ...) %>%\n        as_meta_data(data)\n    data\n}"
  },
  {
    "path": "R/utilities.R",
    "content": "#' @importFrom tibble as_tibble\n#'\n#' @keywords internal\n#'\n#' @param .data A tidyseurat\n#' \n#' @noRd\nto_tib <- function(.data) {\n    .data[[]] %>%\n        as_tibble(rownames=c_(.data)$name)\n}\n\n# Greater than\ngt <- function(a, b) {\n    a > b\n}\n\n# Smaller than\nst <- function(a, b) {\n    a < b\n}\n\n# Negation\nnot <- function(is) {\n    !is\n}\n\n# Raise to the power\npow <- function(a, b) {\n    a^b\n}\n\n# Equals\neq <- function(a, b) {\n    a == b\n}\n\nprepend <- function(x, values, before=1) {\n    n <- length(x)\n    stopifnot(before > 0 && before <= n)\n    if (before == 1) {\n        c(values, x)\n    } else {\n        c(x[seq_len(before-1)], values, x[seq(before, n)])\n    }\n}\n\n#' Add class to abject\n#'\n#' @keywords internal\n#'\n#' @param var A tibble\n#' @param name A character name of the attribute\n#'\n#' @return A tibble with an additional attribute\nadd_class <- function(var, name) {\n    if (!name %in% class(var)) \n        class(var) <- prepend(class(var), name)\n    return(var)\n}\n\n#' Remove class to abject\n#'\n#' @keywords internal\n#'\n#' @param var A tibble\n#' @param name A character name of the class\n#'\n#' @return A tibble with an additional attribute\n#' @keywords internal\ndrop_class <- function(var, name) {\n    class(var) <- class(var)[!class(var) %in% name]\n    return(var)\n}\n\n#' get abundance wide\n#'\n#' @keywords internal\n#'\n#' @importFrom magrittr \"%$%\"\n#' @importFrom utils tail\n#' @importFrom Seurat GetAssayData\n#' @importFrom Seurat DietSeurat\n#' @importFrom SeuratObject DefaultAssay<-\n#' @importFrom stats setNames\n#'\n#' @param .data A tidyseurat\n#' @param features A character\n#' @param all A boolean\n#' @param assay assay name to extract feature abundance\n#' @param slot slot in the assay, e.g. `data` and `scale.data`\n#' @param prefix prefix for the feature names\n#'\n#' @return A Seurat object\n#' @examples\n#' data(pbmc_small)\n#' pbmc_small %>%\n#'   get_abundance_sc_wide(features=c(\"HLA-DRA\", \"LYZ\"))\n#'\n#' @export\nget_abundance_sc_wide <- function(.data, features=NULL, all=FALSE,\n    assay=.data@active.assay, slot=\"data\", prefix=\"\") {\n\n    # Solve CRAN warnings\n    . <- NULL\n    assays <- NULL\n    counts <- NULL\n  \n    if (is.null(assay)) {\n  \t    assay <- .data@active.assay\n    }\n\n    # Check if output would be too big without forcing\n    if(\n        length(VariableFeatures(.data)) == 0  &\n        is.null(features) &\n        all == FALSE\n    ) {\n        stop(\"Your object do not contain variable trancript labels,\\n\",\n\t\t\t \" feature argument is empty and all argument is set to FALSE.\\n\",\n\t\t\t \" Either:\\n\",\n\t\t\t \" 1. use detect_variable_features() to select variable feature\\n\",\n\t\t\t \" 2. pass an array of features names\\n\",\n\t\t\t \" 3. set all=TRUE (this will output a very large object;\",\n             \" does your computer have enough RAM?)\\n\")\n    }\n\n    # Get variable features if existing\n    if(\n        length(VariableFeatures(.data)) > 0  &\n        is.null(features) &\n        all == FALSE\n    ) variable_genes <- VariableFeatures(.data)\n    # Else\n    else variable_genes <- NULL\n\n    # Eliminate unneeded assays.\n    # This because if a gene is not in an assay I am not interested about\n    # this could cause an unneeded error\n    DefaultAssay(.data) <- assay\n    .data = .data |> DietSeurat(assays = assay)\n\n    # Just grub last assay\n    .data |> \n      GetAssayData(assay = assay, layer=slot) %>% \n        when(\n            variable_genes %>% is.null %>% `!` ~ \n                (.)[ toupper(rownames(.)) %in% toupper(variable_genes),,drop=FALSE],\n            features %>% is.null %>% `!` ~ \n                (.)[ toupper(rownames(.)) %in% toupper(features),,drop=FALSE],\n            ~ stop(\"tidyseurat says: It is not convenient to\",\n                \" extract all genes, you should have either variable\",\n                \" features or feature list to extract.\")\n        ) |> \n        as.matrix() |> \n        t() |> \n        as_tibble(rownames=c_(.data)$name) %>%\n\n        # Add prefix\n        setNames(c(c_(.data)$name, sprintf(\"%s%s\", prefix, colnames(.)[-1])))\n}\n\n#' get abundance long\n#'\n#' @keywords internal\n#'\n#' @importFrom magrittr \"%$%\"\n#' @importFrom Seurat VariableFeatures\n#' @importFrom tidyr pivot_longer\n#' @importFrom tibble as_tibble\n#' @importFrom purrr when\n#' @importFrom purrr map2\n#'\n#' @param .data A tidyseurat\n#' @param features A character\n#' @param all A boolean\n#' @param exclude_zeros A boolean\n#' @param assay assay name to extract feature abundance\n#' @param slot slot in the assay, e.g. `data` and `scale.data`\n#'\n#' @return A Seurat object\n#' @examples\n#' data(pbmc_small)\n#' pbmc_small %>%\n#'   get_abundance_sc_long(features=c(\"HLA-DRA\", \"LYZ\"))\n#'\n#' @export\nget_abundance_sc_long <- function(.data, features=NULL, all=FALSE,\n    exclude_zeros=FALSE, assay=Assays(.data), slot=\"data\"){\n\n    # Solve CRAN warnings\n    . <- NULL\n  \n    if (is.null(assay)) {\n  \t    assay <- Assays(.data)\n    }\n  \n    # Check if output would be too big without forcing\n    if (\n        length(VariableFeatures(.data)) == 0  &\n        is.null(features) &\n        all == FALSE\n    ) {\n        stop(\"Your object do not contain variable trancript labels,\\n\",\n        \" feature argument is empty and all argument is set to FALSE.\\n\",\n        \" Either:\\n\",\n        \" 1. use detect_variable_features() to select variable feature\\n\",\n        \" 2. pass an array of features names\\n\",\n        \" 3. set all=TRUE (this will output a very large object;\",\n        \" does your computer have enough RAM?)\\n\")\n    }\n\n\n    # Get variable features if existing\n    if(\n        length(VariableFeatures(.data)) > 0  &\n        is.null(features) &\n        all == FALSE\n    ) variable_genes <- VariableFeatures(.data)\n    # Else\n    else variable_genes <- NULL\n\n    .data@assays %>%\n  \t    .[assay] %>%\n        # Take active assay\n        map2(assay,\n            ~ .x %>%\n                GetAssayData(layer = slot) %>%\n                when(\n                    variable_genes %>% is.null %>% `!` ~\n                        (.)[variable_genes,, drop=FALSE],\n                    features %>% is.null %>% `!` ~ \n                        (.)[ toupper(rownames((.))) %in% \n                            toupper(features), , drop=FALSE],\n                    all ~ (.),\n                    ~ stop(\"tidyseurat says: It is not convenient to\",\n                        \" extract all genes, you should have either variable\",\n                        \" features or feature list to extract.\")\n                ) %>%\n\n                # Replace 0 with NA\n                when(exclude_zeros ~ \n                        (.) %>%\n                        { x=(.); x[x == 0] <- NA; x }, ~ (.)) %>%\n                        data.frame(check.names=FALSE) %>%\n                        as_tibble(rownames=\".feature\") %>%\n                        tidyr::pivot_longer(\n                            cols= - .feature,\n                            names_to=c_(.data)$name,\n                            values_to=\".abundance\" %>% paste(.y, sep=\"_\"),\n                            values_drop_na=TRUE\n                        ) #%>%\n                #mutate_if(is.character, as.factor) %>%\n        ) %>%\n        Reduce(function(...)\n            full_join(..., by=c(\".feature\", c_(.data)$name)), .)\n}\n\n#' @importFrom dplyr select_if\n#' @importFrom tibble column_to_rownames\n#'\n#' @keywords internal\n#'\n#' @param .data A tibble\n#' @param seurat_object A tidyseurat\n#'\n#' @noRd\nas_meta_data <- function(.data, seurat_object){\n\n    # Solve CRAN warnings\n    . <- NULL\n\n    col_to_exclude <- get_special_columns(seurat_object)\n\n    .data %>%\n        select_if(!colnames(.) %in% col_to_exclude) %>%\n        #select(-one_of(col_to_exclude)) %>%\n        column_to_rownames(c_(seurat_object)$name)\n}\n\n#' @importFrom purrr map_chr\n#'\n#' @keywords internal\n#'\n#' @param seurat_object A tidyseurat\n#'\n#' @noRd\nget_special_columns <- function(seurat_object){\n    get_special_datasets(seurat_object) %>%\n        map(~ .x %>% colnames  ) %>%\n        unlist %>%\n        as.character\n}\n\nget_special_datasets <- function(seurat_object, n_dimensions_to_return=Inf){\n    seurat_object@reductions %>%\n        map(~ .x@cell.embeddings[,\n            1:min(n_dimensions_to_return, ncol(.x@cell.embeddings)),\n            drop=FALSE])\n}\n\nget_needed_columns <- function(.data){\n    c(c_(.data)$name)\n}\n\n#' Convert array of quosure (e.g. c(col_a, col_b)) into character vector\n#'\n#' @keywords internal\n#'\n#' @importFrom rlang quo_name\n#' @importFrom rlang quo_squash\n#'\n#' @param v A array of quosures (e.g. c(col_a, col_b))\n#'\n#' @return A character vector\nquo_names <- function(v) {\n    v <- quo_name(quo_squash(v))\n    gsub('^c\\\\(|`|\\\\)$', '', v) %>%\n        strsplit(', ') %>%\n        unlist\n}\n\n\n#' returns variables from an expression\n#' @param expression an expression\n#' @importFrom rlang enexpr\n#' @return list of symbols\nreturn_arguments_of <- function(expression){\n    variables <- enexpr(expression) |> as.list()\n    if(length(variables) > 1) {\n        variables <- variables[-1] # removes first element which is function\n    }\n    variables\n}\n\n#' @importFrom purrr when\n#' @importFrom dplyr select\n#' @importFrom rlang expr\nselect_helper <- function(.data, ...){\n    loc <- tidyselect::eval_select(expr(c(...)), .data)\n    dplyr::select( .data, loc)\n}\n\ndata_frame_returned_message <- paste(\n    \"tidyseurat says:\",\n    \"A data frame is returned for independent data analysis.\")\n\nduplicated_cell_names <- paste(\n    \"tidyseurat says:\",\n    \"This operation lead to duplicated cell names.\",\n    \"A data frame is returned for independent data analysis.\")\n\n#' @importFrom methods .hasSlot\nclean_seurat_object <- function(.data){\n\n    . <- NULL\n\n    if (.hasSlot(.data, \"images\"))\n        .data@images <-\n            map(.data@images,\n                ~ .x %>% when((.)@coordinates %>% nrow() %>% gt(0) ~ (.))) %>%\n\n                # Drop NULL\n                Filter(Negate(is.null), .)\n\n        .data@assays <- .data@assays %>%\n            map(~ {\n                my_assay=.x\n                if (.hasSlot(., \"SCTModel.list\"))\n                    my_assay@SCTModel.list  =\n                    map(my_assay@SCTModel.list,\n                        ~ .x %>%\n                            when((.)@cell.attributes %>%\n                                nrow() %>% gt(0) ~ (.))) %>%\n\n                            # Drop NULL\n                            Filter(Negate(is.null), .)\n                my_assay\n            })\n\n    .data\n}\n\n\n# This function is used for the change of special sample column to .sample\n# Check if \"sample\" is included in the query and\n# is not part of any other existing annotation\n#' @importFrom stringr str_detect\n#' @importFrom stringr regex\nis_sample_feature_deprecated_used <- function(.data, \n    user_columns, use_old_special_names=FALSE) {\n    \n    cell <- any(str_detect(user_columns, regex(\"\\\\bcell\\\\b\")))\n    .cell <- any(str_detect(user_columns, regex(\"\\\\W*(\\\\.cell)\\\\W*\")))\n    \n    old_standard_is_used <- \n        !\"cell\" %in% colnames(.data@meta.data) &&\n        (\"cell\" %in% user_columns || (cell && !.cell))\n    \n    if (old_standard_is_used) {\n        warning(\"tidyseurat says:\",\n            \" from version 1.3.1, the special columns including\",\n            \" cell id (colnames(se)) has changed to \\\".cell\\\".\",\n            \" This dataset is returned with the old-style vocabulary (cell),\",\n            \" however, we suggest to update your workflow\",\n            \" to reflect the new vocabulary (.cell).\")\n        use_old_special_names <- TRUE\n    }\n    use_old_special_names\n}\n\nget_special_column_name_symbol <- function(name){\n    list(name=name, symbol=as.symbol(name))\n}\n\n# Key column names\nping_old_special_column_into_metadata <- function(.data){\n    .data@misc$cell__ <- get_special_column_name_symbol(\"cell\")\n    .data\n}\n\nget_special_column_name_cell <- function(name){\n    list(name=name, symbol=as.symbol(name))\n}\n\ncell__ <- get_special_column_name_symbol(\".cell\")\n\nc_ <- function(x){\n    # Check if old deprecated columns are used\n    if(\"cell__\" %in% names(x@misc)) cell__ <- x@misc$cell__\n    return(cell__)\n}\n\n#' Add attribute to abject\n#'\n#' @keywords internal\n#' @noRd\n#'\n#' @importFrom dplyr vars\n#'\n#' @param var A tibble\n#' @param attribute An object\n#' @param name A character name of the attribute\n#'\n#' @return A tibble with an additional attribute\nadd_attr <- function(var, attribute, name) {\n    attr(var, name) <- attribute\n    var\n}\n\n#' Get specific annotation columns\n#'\n#' @keywords internal\n#' @noRd\n#' \n#' @importFrom rlang enquo\n#' @importFrom purrr map\n#' @importFrom dplyr distinct_at\n#' @importFrom magrittr equals\n#' @importFrom dplyr vars\n#' \n#' @param .data A tibble\n#' @param .col A vector of column names\n#' \n#' @return A character\nget_specific_annotation_columns <- function(.data, .col) {\n    \n    # Comply with CRAN NOTES\n    . <- NULL\n    \n    # Make col names\n    .col <- enquo(.col)\n    \n    # x-annotation df\n    n_x <- .data |> distinct_at(vars(!!.col)) |> nrow()\n    \n    # element wise columns\n    .data |>\n        select(-!!.col) |>\n        colnames() |>\n        map(~ {\n            n_.x <- .data |> distinct_at(vars(!!.col, .x)) |> nrow()\n            if (n_.x == n_x) .x else NULL\n        }) %>%\n        # Drop NULL\n        { (.)[lengths((.)) != 0] } |>\n        unlist()\n}\n\nsubset_tidyseurat <- function(.data, .column) {\n    # Make col names\n    .column <- enquo(.column)\n\n    # Check if column present\n    if (.data |> select(!!.column) |> colnames() %in% colnames(.data) %>% all %>% `!`)\n        stop(\"tidyseurat says: some of the .column specified\",\n            \" do not exist in the input data frame.\")\n\n\n    .data %>%\n    # Selecting the right columns\n        select(!!.column, get_specific_annotation_columns(.data, !!.column)) %>%\n        distinct()\n}\n\n#' @importFrom Seurat GetAssayData\n#' @importFrom methods is\nGetAssayData_robust = function(seurat_assay, layer = NULL){\n  \n  if(\n    seurat_assay |> is(\"Assay5\") & \n    seurat_assay |> ncol() == 1\n  ){\n    m = seurat_assay@layers[[layer]] |> as.matrix()\n    rownames(m) = rownames(seurat_assay)\n    colnames(m) = colnames(seurat_assay)\n    m\n  }\n    \n  else \n    GetAssayData(seurat_assay, layer=layer)\n}\n"
  },
  {
    "path": "R/utils-pipe.R",
    "content": "#' Pipe operator\n#'\n#' See \\code{magrittr::\\link[magrittr:pipe]{\\%>\\%}} for details.\n#'\n#' @name %>%\n#' @rdname pipe\n#' @keywords internal\n#' @export\n#' @importFrom magrittr %>%\n#' @usage lhs \\%>\\% rhs\n#' @examples\n#' data(pbmc_small)\n#' pbmc_small %>% print()\n#' @return void\nNULL\n"
  },
  {
    "path": "R/zzz.R",
    "content": "#' @importFrom utils packageDescription\n.onAttach = function(libname, pkgname) {\n\tversion = packageDescription(pkgname, fields = \"Version\")\n\t\n\tmsg = paste0(\"========================================\n\", pkgname, \" version \", version, \"\nIf you use TIDYSEURAT in published research, please cite:\n\nMangiola et al. Interfacing Seurat with the R tidy universe. Bioinformatics 2021.\n\nThis message can be suppressed by:\n  suppressPackageStartupMessages(library(tidyseurat))\n  \nTo restore the Seurat default display use options(\\\"restore_Seurat_show\\\" = TRUE) \n========================================\n\")\t\n\t\n\tpackageStartupMessage(msg)\n    # Attach tidyverse\n    attached <- tidyverse_attach()\n}\n\n# rv = R.Version()\n\n# if(getRversion() >= \"4.0.0\" && as.numeric(rv$`svn rev`) >= 77889) {\n# \tunitType = get(\"unitType\", envir = asNamespace(\"grid\"))\n# } else {\n# \tunitType = function(x, recurse = TRUE) attr(x, \"unit\")\n# }"
  },
  {
    "path": "README.Rmd",
    "content": "---\ntitle: \"tidyseurat - part of tidytranscriptomics\"\noutput: github_document\nalways_allow_html: true\n---\n\n<!-- badges: start -->\n[![Lifecycle:maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html) [![R build status](https://github.com/stemangiola/tidyseurat/workflows/R-CMD-check/badge.svg)](https://github.com/stemangiola/tidyseurat/actions/)\n<!-- badges: end -->\n\n<a href=\"https://www.youtube.com/watch?feature=player_embedded&v=wKnyocRCvW4\" target=\"_blank\">\n <img src=\"https://img.youtube.com/vi/wKnyocRCvW4/mqdefault.jpg\" alt=\"Watch the video\" width=\"280\" height=\"180\" border=\"10\" />\n</a>\n\n```{r echo=FALSE}\nknitr::opts_chunk$set( fig.path = \"man/figures/\")\n```\n\n```{r include=FALSE}\n# Set path to plotly screenshot. We don't run the plotly code chunk as most servers do not have javascript libraries needed for interactive plotting\nscreenshot <- \"man/figures/plotly.png\"\n\n# The chunk below uses Rmd in man/fragments to avoid duplication, as the content is shared with the vignette and README. As suggested here: https://www.garrickadenbuie.com/blog/dry-vignette-and-readme/\n\nvisual_cue <- \"man/figures/logo_interaction-01.png\"\n\n```\n\n```{r child=\"man/fragments/intro.Rmd\"}\n```\n"
  },
  {
    "path": "README.md",
    "content": "tidyseurat - part of tidytranscriptomics\n================\n\n<!-- badges: start -->\n\n[![Lifecycle:maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html)\n[![R build\nstatus](https://github.com/stemangiola/tidyseurat/workflows/R-CMD-check/badge.svg)](https://github.com/stemangiola/tidyseurat/actions/)\n<!-- badges: end -->\n\n<a href=\"https://www.youtube.com/watch?feature=player_embedded&v=wKnyocRCvW4\" target=\"_blank\">\n<img src=\"https://img.youtube.com/vi/wKnyocRCvW4/mqdefault.jpg\" alt=\"Watch the video\" width=\"280\" height=\"180\" border=\"10\" />\n</a>\n\n**Brings Seurat to the tidyverse!**\n\nwebsite:\n[stemangiola.github.io/tidyseurat/](https://stemangiola.github.io/tidyseurat/)\n\nPlease also have a look at\n\n- [tidyseurat](https://stemangiola.github.io/tidyseurat/) for tidy\n  single-cell RNA sequencing analysis\n- [tidySummarizedExperiment](https://tidyomics.github.io/tidySummarizedExperiment/)\n  for tidy bulk RNA sequencing analysis\n- [tidybulk](https://tidyomics.github.io/tidybulk/) for tidy bulk\n  RNA-seq analysis\n- [tidygate](https://github.com/stemangiola/tidygate/) for adding custom\n  gate information to your tibble\n- [tidyHeatmap](https://stemangiola.github.io/tidyHeatmap/) for heatmaps\n  produced with tidy principles\n\n<figure>\n<img src=\"man/figures/logo_interaction-01.png\" alt=\"visual cue\" />\n<figcaption aria-hidden=\"true\">visual cue</figcaption>\n</figure>\n\n# Introduction\n\ntidyseurat provides a bridge between the Seurat single-cell package\n\\[@butler2018integrating; @stuart2019comprehensive\\] and the tidyverse\n\\[@wickham2019welcome\\]. It creates an invisible layer that enables\nviewing the Seurat object as a tidyverse tibble, and provides\nSeurat-compatible *dplyr*, *tidyr*, *ggplot* and *plotly* functions.\n\n## Functions/utilities available\n\n| Seurat-compatible Functions | Description |\n|-----------------------------|-------------|\n| `all`                       |             |\n\n| tidyverse Packages | Description                          |\n|--------------------|--------------------------------------|\n| `dplyr`            | All `dplyr` APIs like for any tibble |\n| `tidyr`            | All `tidyr` APIs like for any tibble |\n| `ggplot2`          | `ggplot` like for any tibble         |\n| `plotly`           | `plot_ly` like for any tibble        |\n\n| Utilities | Description |\n|----|----|\n| `tidy` | Add `tidyseurat` invisible layer over a Seurat object |\n| `as_tibble` | Convert cell-wise information to a `tbl_df` |\n| `join_features` | Add feature-wise information, returns a `tbl_df` |\n| `aggregate_cells` | Aggregate cell gene-transcription abundance as pseudobulk tissue |\n\n## Installation\n\nFrom CRAN\n\n``` r\ninstall.packages(\"tidyseurat\")\n```\n\nFrom Github (development)\n\n``` r\ndevtools::install_github(\"stemangiola/tidyseurat\")\n```\n\n``` r\nlibrary(dplyr)\nlibrary(tidyr)\nlibrary(purrr)\nlibrary(magrittr)\nlibrary(ggplot2)\nlibrary(Seurat)\nlibrary(tidyseurat)\n```\n\n## Create `tidyseurat`, the best of both worlds!\n\nThis is a seurat object but it is evaluated as tibble. So it is fully\ncompatible both with Seurat and tidyverse APIs.\n\n``` r\npbmc_small = SeuratObject::pbmc_small\n```\n\n**It looks like a tibble**\n\n``` r\npbmc_small\n```\n\n    ## # A Seurat-tibble abstraction: 80 × 15\n    ## # [90mFeatures=230 | Cells=80 | Active assay=RNA | Assays=RNA[0m\n    ##    .cell orig.ident nCount_RNA nFeature_RNA RNA_snn_res.0.8 letter.idents groups\n    ##    <chr> <fct>           <dbl>        <int> <fct>           <fct>         <chr> \n    ##  1 ATGC… SeuratPro…         70           47 0               A             g2    \n    ##  2 CATG… SeuratPro…         85           52 0               A             g1    \n    ##  3 GAAC… SeuratPro…         87           50 1               B             g2    \n    ##  4 TGAC… SeuratPro…        127           56 0               A             g2    \n    ##  5 AGTC… SeuratPro…        173           53 0               A             g2    \n    ##  6 TCTG… SeuratPro…         70           48 0               A             g1    \n    ##  7 TGGT… SeuratPro…         64           36 0               A             g1    \n    ##  8 GCAG… SeuratPro…         72           45 0               A             g1    \n    ##  9 GATA… SeuratPro…         52           36 0               A             g1    \n    ## 10 AATG… SeuratPro…        100           41 0               A             g1    \n    ## # ℹ 70 more rows\n    ## # ℹ 8 more variables: RNA_snn_res.1 <fct>, PC_1 <dbl>, PC_2 <dbl>, PC_3 <dbl>,\n    ## #   PC_4 <dbl>, PC_5 <dbl>, tSNE_1 <dbl>, tSNE_2 <dbl>\n\n**But it is a Seurat object after all**\n\n``` r\npbmc_small@assays\n```\n\n    ## $RNA\n    ## Assay data with 230 features for 80 cells\n    ## Top 10 variable features:\n    ##  PPBP, IGLL5, VDAC3, CD1C, AKR1C3, PF4, MYL9, GNLY, TREML1, CA2\n\n# Preliminary plots\n\nSet colours and theme for plots.\n\n``` r\n# Use colourblind-friendly colours\nfriendly_cols <- c(\"#88CCEE\", \"#CC6677\", \"#DDCC77\", \"#117733\", \"#332288\", \"#AA4499\", \"#44AA99\", \"#999933\", \"#882255\", \"#661100\", \"#6699CC\")\n\n# Set theme\nmy_theme <-\n  list(\n    scale_fill_manual(values = friendly_cols),\n    scale_color_manual(values = friendly_cols),\n    theme_bw() +\n      theme(\n        panel.border = element_blank(),\n        axis.line = element_line(),\n        panel.grid.major = element_line(size = 0.2),\n        panel.grid.minor = element_line(size = 0.1),\n        text = element_text(size = 12),\n        legend.position = \"bottom\",\n        aspect.ratio = 1,\n        strip.background = element_blank(),\n        axis.title.x = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),\n        axis.title.y = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10))\n      )\n  )\n```\n\nWe can treat `pbmc_small` effectively as a normal tibble for plotting.\n\nHere we plot number of features per cell.\n\n``` r\npbmc_small %>%\n  ggplot(aes(nFeature_RNA, fill = groups)) +\n  geom_histogram() +\n  my_theme\n```\n\n![](man/figures/plot1-1.png)<!-- -->\n\nHere we plot total features per cell.\n\n``` r\npbmc_small %>%\n  ggplot(aes(groups, nCount_RNA, fill = groups)) +\n  geom_boxplot(outlier.shape = NA) +\n  geom_jitter(width = 0.1) +\n  my_theme\n```\n\n![](man/figures/plot2-1.png)<!-- -->\n\nHere we plot abundance of two features for each group.\n\n``` r\npbmc_small %>%\n  join_features(features = c(\"HLA-DRA\", \"LYZ\"), shape = \"long\") %>%\n  ggplot(aes(groups, .abundance_RNA + 1, fill = groups)) +\n  geom_boxplot(outlier.shape = NA) +\n  geom_jitter(aes(size = nCount_RNA), alpha = 0.5, width = 0.2) +\n  scale_y_log10() +\n  my_theme\n```\n\n![](man/figures/unnamed-chunk-15-1.png)<!-- -->\n\n# Preprocess the dataset\n\nAlso you can treat the object as Seurat object and proceed with data\nprocessing.\n\n``` r\npbmc_small_pca <-\n  pbmc_small %>%\n  SCTransform(verbose = FALSE) %>%\n  FindVariableFeatures(verbose = FALSE) %>%\n  RunPCA(verbose = FALSE)\n\npbmc_small_pca\n```\n\n    ## # A Seurat-tibble abstraction: 80 × 17\n    ## # [90mFeatures=220 | Cells=80 | Active assay=SCT | Assays=RNA, SCT[0m\n    ##    .cell orig.ident nCount_RNA nFeature_RNA RNA_snn_res.0.8 letter.idents groups\n    ##    <chr> <fct>           <dbl>        <int> <fct>           <fct>         <chr> \n    ##  1 ATGC… SeuratPro…         70           47 0               A             g2    \n    ##  2 CATG… SeuratPro…         85           52 0               A             g1    \n    ##  3 GAAC… SeuratPro…         87           50 1               B             g2    \n    ##  4 TGAC… SeuratPro…        127           56 0               A             g2    \n    ##  5 AGTC… SeuratPro…        173           53 0               A             g2    \n    ##  6 TCTG… SeuratPro…         70           48 0               A             g1    \n    ##  7 TGGT… SeuratPro…         64           36 0               A             g1    \n    ##  8 GCAG… SeuratPro…         72           45 0               A             g1    \n    ##  9 GATA… SeuratPro…         52           36 0               A             g1    \n    ## 10 AATG… SeuratPro…        100           41 0               A             g1    \n    ## # ℹ 70 more rows\n    ## # ℹ 10 more variables: RNA_snn_res.1 <fct>, nCount_SCT <dbl>,\n    ## #   nFeature_SCT <int>, PC_1 <dbl>, PC_2 <dbl>, PC_3 <dbl>, PC_4 <dbl>,\n    ## #   PC_5 <dbl>, tSNE_1 <dbl>, tSNE_2 <dbl>\n\nIf a tool is not included in the tidyseurat collection, we can use\n`as_tibble` to permanently convert `tidyseurat` into tibble.\n\n``` r\npbmc_small_pca %>%\n  as_tibble() %>%\n  select(contains(\"PC\"), everything()) %>%\n  GGally::ggpairs(columns = 1:5, ggplot2::aes(colour = groups)) +\n  my_theme\n```\n\n![](man/figures/pc_plot-1.png)<!-- -->\n\n# Identify clusters\n\nWe proceed with cluster identification with Seurat.\n\n``` r\npbmc_small_cluster <-\n  pbmc_small_pca %>%\n  FindNeighbors(verbose = FALSE) %>%\n  FindClusters(method = \"igraph\", verbose = FALSE)\n\npbmc_small_cluster\n```\n\n    ## # A Seurat-tibble abstraction: 80 × 19\n    ## # [90mFeatures=220 | Cells=80 | Active assay=SCT | Assays=RNA, SCT[0m\n    ##    .cell orig.ident nCount_RNA nFeature_RNA RNA_snn_res.0.8 letter.idents groups\n    ##    <chr> <fct>           <dbl>        <int> <fct>           <fct>         <chr> \n    ##  1 ATGC… SeuratPro…         70           47 0               A             g2    \n    ##  2 CATG… SeuratPro…         85           52 0               A             g1    \n    ##  3 GAAC… SeuratPro…         87           50 1               B             g2    \n    ##  4 TGAC… SeuratPro…        127           56 0               A             g2    \n    ##  5 AGTC… SeuratPro…        173           53 0               A             g2    \n    ##  6 TCTG… SeuratPro…         70           48 0               A             g1    \n    ##  7 TGGT… SeuratPro…         64           36 0               A             g1    \n    ##  8 GCAG… SeuratPro…         72           45 0               A             g1    \n    ##  9 GATA… SeuratPro…         52           36 0               A             g1    \n    ## 10 AATG… SeuratPro…        100           41 0               A             g1    \n    ## # ℹ 70 more rows\n    ## # ℹ 12 more variables: RNA_snn_res.1 <fct>, nCount_SCT <dbl>,\n    ## #   nFeature_SCT <int>, SCT_snn_res.0.8 <fct>, seurat_clusters <fct>,\n    ## #   PC_1 <dbl>, PC_2 <dbl>, PC_3 <dbl>, PC_4 <dbl>, PC_5 <dbl>, tSNE_1 <dbl>,\n    ## #   tSNE_2 <dbl>\n\nNow we can interrogate the object as if it was a regular tibble data\nframe.\n\n``` r\npbmc_small_cluster %>%\n  count(groups, seurat_clusters)\n```\n\n    ## # A tibble: 6 × 3\n    ##   groups seurat_clusters     n\n    ##   <chr>  <fct>           <int>\n    ## 1 g1     0                  23\n    ## 2 g1     1                  17\n    ## 3 g1     2                   4\n    ## 4 g2     0                  17\n    ## 5 g2     1                  13\n    ## 6 g2     2                   6\n\nWe can identify cluster markers using Seurat.\n\n<!-- If this is Seurat v4, comment out the v3 markers -->\n\n<!--\n&#10;\n``` r\n# Identify top 10 markers per cluster\nmarkers <-\n  pbmc_small_cluster %>%\n  mutate(orig.ident = seurat_clusters) %>% \n  FindAllMarkers(only.pos = TRUE) %>%\n  group_by(cluster) %>%\n  top_n(10, avg_logFC)\n&#10;# Plot heatmap\npbmc_small_cluster %>%\n  DoHeatmap(\n    features = markers$gene,\n    group.colors = friendly_cols\n  )\n```\n&#10;-->\n\n<!-- If this is Seurat v3, comment out the v4 markers -->\n\n``` r\n# Identify top 10 markers per cluster\nmarkers <-\n  pbmc_small_cluster %>%\n  FindAllMarkers(only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25) %>%\n  group_by(cluster) %>%\n  top_n(10, avg_log2FC)\n\n# Plot heatmap\npbmc_small_cluster %>%\n  DoHeatmap(\n    features = markers$gene,\n    group.colors = friendly_cols\n  )\n```\n\n# Reduce dimensions\n\nWe can calculate the first 3 UMAP dimensions using the Seurat framework.\n\n``` r\npbmc_small_UMAP <-\n  pbmc_small_cluster %>%\n  RunUMAP(reduction = \"pca\", dims = 1:15, n.components = 3L)\n```\n\nAnd we can plot them using 3D plot using plotly.\n\n``` r\npbmc_small_UMAP %>%\n  plot_ly(\n    x = ~`UMAP_1`,\n    y = ~`UMAP_2`,\n    z = ~`UMAP_3`,\n    color = ~seurat_clusters,\n    colors = friendly_cols[1:4]\n  )\n```\n\n<figure>\n<img src=\"man/figures/plotly.png\" alt=\"screenshot plotly\" />\n<figcaption aria-hidden=\"true\">screenshot plotly</figcaption>\n</figure>\n\n## Cell type prediction\n\nWe can infer cell type identities using *SingleR* \\[@aran2019reference\\]\nand manipulate the output using tidyverse.\n\n``` r\n# Get cell type reference data\nblueprint <- celldex::BlueprintEncodeData()\n\n# Infer cell identities\ncell_type_df <-\n  GetAssayData(pbmc_small_UMAP, slot = 'counts', assay = \"SCT\") %>%\n  log1p() %>%\n  Matrix::Matrix(sparse = TRUE) %>%\n  SingleR::SingleR(\n    ref = blueprint,\n    labels = blueprint$label.main,\n    method = \"single\"\n  ) %>%\n  as.data.frame() %>%\n  as_tibble(rownames = \"cell\") %>%\n  select(cell, first.labels)\n```\n\n``` r\n# Join UMAP and cell type info\npbmc_small_cell_type <-\n  pbmc_small_UMAP %>%\n  left_join(cell_type_df, by = \"cell\")\n\n# Reorder columns\npbmc_small_cell_type %>%\n  select(cell, first.labels, everything())\n```\n\nWe can easily summarise the results. For example, we can see how cell\ntype classification overlaps with cluster classification.\n\n``` r\npbmc_small_cell_type %>%\n  count(seurat_clusters, first.labels)\n```\n\nWe can easily reshape the data for building information-rich faceted\nplots.\n\n``` r\npbmc_small_cell_type %>%\n\n  # Reshape and add classifier column\n  pivot_longer(\n    cols = c(seurat_clusters, first.labels),\n    names_to = \"classifier\", values_to = \"label\"\n  ) %>%\n\n  # UMAP plots for cell type and cluster\n  ggplot(aes(UMAP_1, UMAP_2, color = label)) +\n  geom_point() +\n  facet_wrap(~classifier) +\n  my_theme\n```\n\nWe can easily plot gene correlation per cell category, adding\nmulti-layer annotations.\n\n``` r\npbmc_small_cell_type %>%\n\n  # Add some mitochondrial abundance values\n  mutate(mitochondrial = rnorm(n())) %>%\n\n  # Plot correlation\n  join_features(features = c(\"CST3\", \"LYZ\"), shape = \"wide\") %>%\n  ggplot(aes(CST3 + 1, LYZ + 1, color = groups, size = mitochondrial)) +\n  geom_point() +\n  facet_wrap(~first.labels, scales = \"free\") +\n  scale_x_log10() +\n  scale_y_log10() +\n  my_theme\n```\n\n# Nested analyses\n\nA powerful tool we can use with tidyseurat is `nest`. We can easily\nperform independent analyses on subsets of the dataset. First we\nclassify cell types in lymphoid and myeloid; then, nest based on the new\nclassification\n\n``` r\npbmc_small_nested <-\n  pbmc_small_cell_type %>%\n  filter(first.labels != \"Erythrocytes\") %>%\n  mutate(cell_class = if_else(`first.labels` %in% c(\"Macrophages\", \"Monocytes\"), \"myeloid\", \"lymphoid\")) %>%\n  nest(data = -cell_class)\n\npbmc_small_nested\n```\n\nNow we can independently for the lymphoid and myeloid subsets (i) find\nvariable features, (ii) reduce dimensions, and (iii) cluster using both\ntidyverse and Seurat seamlessly.\n\n``` r\npbmc_small_nested_reanalysed <-\n  pbmc_small_nested %>%\n  mutate(data = map(\n    data, ~ .x %>%\n      FindVariableFeatures(verbose = FALSE) %>%\n      RunPCA(npcs = 10, verbose = FALSE) %>%\n      FindNeighbors(verbose = FALSE) %>%\n      FindClusters(method = \"igraph\", verbose = FALSE) %>%\n      RunUMAP(reduction = \"pca\", dims = 1:10, n.components = 3L, verbose = FALSE)\n  ))\n\npbmc_small_nested_reanalysed\n```\n\nNow we can unnest and plot the new classification.\n\n``` r\npbmc_small_nested_reanalysed %>%\n\n  # Convert to tibble otherwise Seurat drops reduced dimensions when unifying data sets.\n  mutate(data = map(data, ~ .x %>% as_tibble())) %>%\n  unnest(data) %>%\n\n  # Define unique clusters\n  unite(\"cluster\", c(cell_class, seurat_clusters), remove = FALSE) %>%\n\n  # Plotting\n  ggplot(aes(UMAP_1, UMAP_2, color = cluster)) +\n  geom_point() +\n  facet_wrap(~cell_class) +\n  my_theme\n```\n\n# Aggregating cells\n\nSometimes, it is necessary to aggregate the gene-transcript abundance\nfrom a group of cells into a single value. For example, when comparing\ngroups of cells across different samples with fixed-effect models.\n\nIn tidyseurat, cell aggregation can be achieved using the\n`aggregate_cells` function.\n\n``` r\npbmc_small %>%\n  aggregate_cells(groups, assays = \"RNA\")\n```\n"
  },
  {
    "path": "_pkgdown.yml",
    "content": "template:\n  bootstrap: 5\n"
  },
  {
    "path": "codecov.yml",
    "content": "comment: false\n\ncoverage:\n  status:\n    project:\n      default:\n        target: auto\n        threshold: 1%\n    patch:\n      default:\n        target: auto\n        threshold: 1%\n"
  },
  {
    "path": "dev/code_comparison.Rmd",
    "content": "---\ntitle: \"Code comparison with Seurat\"\nauthor: \"Stefano Mangiola\"\ndate: \"`r Sys.Date()`\"\npackage: tidyseurat\noutput:\n  html_vignette:\n    toc_float: true\nvignette: >\n  %\\VignetteEngine{knitr::knitr}\n  %\\VignetteIndexEntry{Code comparison with Seurat}\n  %\\usepackage[UTF-8]{inputenc}\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\n```\n\n# Case study code comparison\n\n\n## Calculate gamma-delta signature and plot\n\ntidyseurat\n\n```{r}\nseurat_obj <- readRDS(\"dev/PBMC_tidy_clean_scaled_UMAP_cluster_cell_type.rds\")\n\nseurat_obj = \n  seurat_obj %>%\n  filter(first.labels == \"T_cells\") %>%\n  RunPCA() %>% \n  RunUMAP(dims=1:30) %>%\n  mutate(type=case_when(sample %in% c(\"GSE115189\", \"SRR11038995\", \"SRR7244582\") ~ \"A\", TRUE ~ \"B\"))\n\n```\n\n```{r}\n\nlibrary(tidygate)\nlibrary(ggplot2)\nlibrary(purrr)\nlibrary(patchwork)\n\n# Calculate gamma delta signature\nseurat_obj_sig = \n\n\tseurat_obj %>%\n\tjoin_features(\n\t  features = c(\"CD3D\", \"TRDC\", \"TRGC1\", \"TRGC2\", \"CD8A\", \"CD8B\"), \n\t  shape = \"wide\", \n\t  assay = \"SCT\"\n\t) %>%\n\t\n\n\tmutate(signature_score = \n\t         scales::rescale(CD3D + TRDC + TRGC1 + TRGC2, to=c(0,1)) - \n\t         scales::rescale(CD8A + CD8B, to=c(0,1))\n\t) \n\np1 = seurat_obj_sig %>%\n  \n  \n  # Subsample\n  add_count(sample, name = \"tot_cells\") %>%\n  mutate(min_cells = min(tot_cells)) %>%\n  group_by(sample) %>%\n  sample_n(min_cells) %>%\n  \n  # Plot\n  pivot_longer(cols=c(\"CD3D\", \"TRDC\", \"TRGC1\", \"TRGC2\", \"CD8A\", \"CD8B\", \"signature_score\")) %>%\n  mutate(value = case_when(value>0 ~ value)) %>%\n  group_by(name) %>%\n  mutate(value = scale(value)) %>%\n  ggplot(aes(UMAP_1, UMAP_2, color=value)) +\n  geom_point(shape=\".\") +\n  facet_grid(type~name) +\n  scale_color_viridis_c() +\n  custom_theme\n\n# Test differential abundance\np2 = seurat_obj_sig %>%\n  \n  # Gating\n  mutate(gamma_delta = gate_chr(\n\t\tUMAP_1,\n\t\tUMAP_2, \n\t\t.color =  signature_score, \n\t\t.size=0.1\n\t)) %>%\n\n  # Calculate proportions\n  add_count(sample, name = \"tot_cells\") %>%\n  count(sample, type, tot_cells, gamma_delta) %>%\n  mutate(frac = n/tot_cells) %>%\n  filter(gamma_delta == 1) %>%\n  \n  # Plot\n  ggplot(aes(type, frac)) + \n  geom_boxplot() + \n  geom_point() +\n  custom_theme\n\np = p1 / (p2  | plot_spacer()) +  plot_layout(guides = \"collect\")\n\nggsave(\"dev/summary_statistics.pdf\", p,  device = \"pdf\", width = 183, height = 150, units = \"mm\", useDingbats=FALSE)\n\n```\n\nSeurat\n\n```{r}\nlibrary(Seurat)\nlibrary(gatepoints)\nlibrary(dplyr)\n\n# Calculate gamma delta signature\nsignature_score_1 = \n  seurat_obj[c(\"CD3D\", \"TRDC\", \"TRGC1\", \"TRGC2\"),] %>%\n  GetAssayData(assay=\"SCT\", slot=\"data\") %>%\n  colSums() %>%\n  scales::rescale(to=c(0,1))\n\nsignature_score_2 = \n  seurat_obj[c(\"CD8A\", \"CD8B\"),] %>%\n  GetAssayData(assay=\"SCT\", slot=\"data\") %>%\n  colSums() %>%\n  scales::rescale(to=c(0,1))\nseurat_obj$signature_score = signature_score_1 - signature_score_2\n\n# Subsample\nsplits = colnames(seurat_obj) %>% split(seurat_obj$sample) \nmin_size = splits %>% sapply(length) %>%  min()\ncell_subset = splits %>%  lapply(function(x) sample(x, min_size)) %>%  unlist()\nseurat_obj = seurat_obj[,cell_subset]\n\n# Plot\nDefaultAssay(seurat_obj) = \"SCT\"\n\nseurat_obj %>%\nFeaturePlot(\n  features = c(\"signature_score\", \"CD3D\", \"TRDC\", \"TRGC1\", \"TRGC2\", \"CD8A\", \"CD8B\"),\n  split.by = \"type\",\n  min.cutoff = 0.1\n) \n  \n\n# Gating\np = FeaturePlot(seurat_obj, features = \"signature_score\")\nseurat_obj$within_gate = colnames(seurat_obj) %in% CellSelector(plot = p)\n\n# Calculate proportions\nseurat_obj[[]] %>%\n  add_count(sample, name = \"tot_cells\") %>%\n  count(sample, type, tot_cells, within_gate) %>%\n  mutate(frac = n/tot_cells) %>%\n  filter(within_gate == T) %>%\n  \n  # Plot\n  ggplot(aes(type, frac)) + \n  geom_boxplot() + \n  geom_point()\n```"
  },
  {
    "path": "dev/plot_seurat_structure.R",
    "content": "\nlibrary( DataExplorer )\n\nplot_str(pbmc_small, type = \"r\" )\nplot_str(pbmc_small , type=\"d\")\n\nplot_str(pbmc_small %>%  join_features(\"CD3G\"), type = \"r\" )\nplot_str(pbmc_small %>%  join_features(\"CD3G\"), type = \"d\" )\n"
  },
  {
    "path": "dev/use_cases_BioCAsia2021.R",
    "content": "library(tidyverse)\nlibrary(glue)\n\ntibble(\n  observation = glue(\"observation {1:100}\"),\n  variable_1 = rep(\"...\", 100),\n  variable_2 = rep(\"...\", 100),\n  variable_3 = map(1:100, ~ tibble(a = 1:10, b = 1:10)), \n  variable_4 = map(1:100, ~ ggplot()),\n  variable_5 = map(1:100, ~ lm(y ~ x, data = data.frame(x=1:10, y=1:10))),\n  variable_6 = map(1:100, ~ pbmc_small),\n  variable_7 = map(1:100, ~ tidySingleCellExperiment::pbmc_small)\n)\n\n\nmy_vector = seq(1, 20); \n\n# Imperative\nmy_vector_modified = c()\nfor(i in 1:length(my_vector)) {\n  my_vector_modified[i] = my_vector[i] * 2L\n}\n# Functional\nmy_vector_modified = my_vector |> map_int(~ .x * 2L)\n\ndf = data.frame(a= rep(\"a\", ncol(SeuratObject::pbmc_small)), b= rep(\"b\", ncol(SeuratObject::pbmc_small)))\nrownames(df)  = colnames(SeuratObject::pbmc_small)\n\ninfo = rep(1, ncol(SeuratObject::pbmc_small))\nSeuratObject::pbmc_small |>\n  AddMetaData(info, \"info\")\n\ncolData(tidySingleCellExperiment::pbmc_small) |> cbind()\n\n\n# Subsampling\n\nsingle_cell_data |>\n  add_count(sample, name = \"tot_cells\") |>\n  mutate(median_cells = min(tot_cells)) |>\n  nest(data = -c(sample, median_cells)) |>\n  mutate(data = map2(data, median_cells, ~ sample_n(.x, .y, replace = TRUE))) |>\n  unnest(data)\n\n# Define cell categories for analysis plotting\n\nsingle_cell_data |>\n  \n  mutate(cell_differentiation = \n           case_when(\n             curated_cell_type_pretty %in% c(\"B immature\", \"B mem\") ~ \"B\",\n             curated_cell_type_pretty %in% c(\"pDC\") ~ \"pDC\",\n             cell_differentiation == \"lymphoid\" ~ \"T+NK\",\n             cell_differentiation == \"myeloid\" ~ \"Myeloid\"\n           )\n  ) |> \n  \n  mutate(\n    curated_cell_type_pretty = if_else(\n      curated_cell_type_pretty %in% c(\"T gd1\",  \"T gd2\"), \n      \"gamma_delta\" , \n      curated_cell_type_pretty\n    )\n  ) \n\n\n# Quality control\n\n\n\n\n# Gating gamma delta\nseurat_obj_sig = seurat_obj |>\n  \n  \n  join_features(\n    features = c(\"CD3D\", \"TRDC\", \"TRGC1\", \"TRGC2\", \"CD8A\", \"CD8B\"),\n    shape = \"wide\",\n    assay = \"SCT\"\n    \n  ) |>\n  \n  mutate(signature_score =\n           scales::rescale(CD3D + TRDC + TRGC1+ TRGC2, to=c(0,1)) -\n           scales::rescale(CD8A + CD8B, to=c(0,1))\n  ) |>\n  \n  Seurat::FeaturePlot(signature_score) |>\n  mutate( gate = tidygate::gate_int(UMAP_1, UMAP_2) ) |> \n  \n  filter(gate == 1) %>%\n  \n  NormalizeData() |> \n  FindVariableFeatures( nfeatures = 100)\n\n  split_group(sample) %>% \n  RunFastMNN() |> \n  RunUMAP(reduction = \"mnn\", dims = 1:20) |> \n  FindNeighbors( dims = 1:20, reduction = \"mnn\") |> \n  FindClusters( resolution = 0.3) |>\n\n\n# gamma_delta_df = \n#   readRDS(\"cancer_only_analyses/integrated_counts_curated.rds\")  |> \n#   #\t{.x = (.); DefaultAssay(.x) = \"RNA\"; .x} |> \n#   filter(curated_cell_type_pretty %in% c(\"T gd1\",  \"T gd2\")) |> \n#   \n#   {\n#     .x= (.)\n#     DefaultAssay(.x) = \"RNA\"\n#     .x[[\"SCT\"]] = NULL\n#     .x[[\"integrated\"]] = NULL\n#     .x\n#   } |> \n#   NormalizeData() |> \n#   FindVariableFeatures( nfeatures = 100) |> \n#   mutate(batch_to_eliminate = sample) |> \n#   nest(data = -batch_to_eliminate) |>\n#   pull(data) |> \n#   RunFastMNN() |> \n#   RunUMAP(reduction = \"mnn\", dims = 1:20) |> \n#   FindNeighbors( dims = 1:20, reduction = \"mnn\") |> \n#   FindClusters( resolution = 0.3) |>\n#   mutate(gate = tidygate::gate_int(UMAP_1, UMAP_2, how_many_gates = 2, gate_list = readRDS(\"file66175abbca44.rds\"))) |> \n#   tidysc::adjust_abundance(~ 1) |>\n#   mutate(gamma_delta = case_when(\n#     gate == 0 ~ \"T gd vd2\",\n#     gate == 1 ~ \"T gd vd1 LGALS1\",\n#     gate == 2 ~ \"T gd vd1\",\n#   ))"
  },
  {
    "path": "dev/workflow_article.R",
    "content": "# Article workflow\nlibrary(tidyverse)\nlibrary(Seurat)\nlibrary(SingleR)\nlibrary(plotly)\nlibrary(tidyHeatmap)\nlibrary(tidyseurat)\noptions(future.globals.maxSize = 50068 * 1024^2)\n\nPBMC <- readRDS(\"dev/PBMC_integrated.rds\")\n\n# Polishing\n\nPBMC_clean <-\n  PBMC_\n\n  # Clean groups\n  mutate(Phase = Phase %>% str_remove(\"^phase_\")) %>%\n\n  # Extract sample\n  extract(sample, \"sample\", \"./data/seurat/outs/([a-zA-Z0-9]+)\")\n\n# PBMC_clean = PBMC_clean %>% nest(data = -sample) %>% mutate(data = map(data, ~ .x %>% sample_n(200))) %>% unnest(data)\n\n# Scaling\n# PBMC_clean_scaled <-\n#   PBMC_clean %>%\n#    SCTransform(verbose = FALSE) %>%\n#   FindVariableFeatures(verbose = FALSE)\n\n\n# Dimensionality reduction\nPBMC_clean_scaled_UMAP <-\n  PBMC_clean %>%\n  RunPCA(verbose = FALSE) %>%\n  RunUMAP(reduction = \"pca\", dims = 1:15, n.components = 3L)\n\n# Clustering\nPBMC_clean_scaled_UMAP_cluster <-\n  PBMC_clean_scaled_UMAP %>%\n  FindNeighbors(verbose = FALSE) %>%\n  FindClusters(method = \"igraph\", verbose = FALSE)\n\n# Cell_type classification Manual\nmarkers <-\n  PBMC_clean_scaled_UMAP_cluster %>%\n  FindAllMarkers(only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25) %>%\n  group_by(cluster) %>%\n  top_n(10, avg_logFC)\n\n# Cell_type classification Automatic\n\n# Get cell type reference data\nhpca <- HumanPrimaryCellAtlasData()\n\n# Infer cell identities\ncell_type_df <-\n\n  # extracting counts from Seurat object\n  GetAssayData(PBMC_clean_scaled_UMAP_cluster, layer = 'counts', assay = \"SCT\") %>%\n  log1p() %>%\n\n  # SingleR\n  SingleR(\n    ref = hpca,\n    labels = hpca$label.main,\n    method = \"cluster\",\n    clusters = PBMC_clean_scaled_UMAP_cluster %>% pull(seurat_clusters)\n  ) %>%\n\n  # Formatting results\n  as.data.frame() %>%\n  as_tibble(rownames = \"seurat_clusters\") %>%\n  select(seurat_clusters, first.labels)\n\n\n# Infer cell identities - cell wise\ncell_type_df_single <-\n\n  # extracting counts from Seurat object\n  GetAssayData(PBMC_clean_scaled_UMAP_cluster, layer = 'counts', assay = \"SCT\") %>%\n  log1p() %>%\n\n  # SingleR\n  SingleR(\n    ref = hpca,\n    labels = hpca$label.main,\n    method = \"single\"\n  ) %>%\n\n  # Formatting results\n  as.data.frame() %>%\n  as_tibble(rownames = \"cell\") %>%\n  select(cell, first.labels_single = first.labels)\n\n# Join UMAP and cell type info\nPBMC_clean_scaled_UMAP_cluster_cell_type <-\n  PBMC_clean_scaled_UMAP_cluster %>%\n  left_join(\n    cell_type_df,\n    by = \"seurat_clusters\"\n  ) %>%\n  left_join(\n    cell_type_df_single,\n    by = \"cell\"\n  )\n\n\n# Markers\nPBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  FindAllMarkers(only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25) %>%\n  group_by(cluster) %>%\n  top_n(10, avg_logFC) %>%\n  saveRDS(\"dev/PBMC_marker_df.rds\")\n\n# Nesting\nPBMC_clean_scaled_UMAP_cluster_cell_type  %>%\n  sample_n(1000) %>%\n\n  # Label lymphoid and myeloid\n  tidyseurat::filter(first.labels != \"Platelets\") %>%\n  tidyseurat::mutate(cell_class =\n                       if_else(\n                         `first.labels` %in% c(\"Macrophage\", \"Monocyte\"),\n                         \"myeloid\",\n                         \"lymphoid\"\n                       )\n  ) %>%\n\n  # Nesting\n  nest(data = -cell_class) %>%\n\n  # Identification of variable gene features\n  mutate(variable_genes = map_chr(\n    data, ~ .x %>%\n      FindVariableFeatures() %>%\n      RunPCA(verbose = FALSE) %>%\n      FindAllMarkers(only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25) %>%\n      pull(gene) %>%\n      head() %>%\n      paste(collapse=\", \")\n  ))\n\n# # Reorder columns\n# PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n#   count(seurat_clusters, first.labels_cluster = first.labels)\n\nsaveRDS(PBMC_clean_scaled_UMAP_cluster_cell_type, \"dev/PBMC_clean_scaled_UMAP_cluster_cell_type.rds\")\n"
  },
  {
    "path": "dev/workflow_create_integrated_pbmc.R",
    "content": "# Article workflow\n\nlibrary(tidyverse)\nlibrary(Seurat)\nlibrary(SingleR)\nlibrary(plotly)\n# library(future)\n# plan(multisession, workers=10)\noptions(future.globals.maxSize = 50068 * 1024^2)\nlibrary(tidyseurat)\nfriendly_cols <- dittoSeq::dittoColors()\n\n# PBMC = PBMC %>% \n#   select(1:11, -old.ident) %>%\n#   mutate(sample = sprintf(\"./data/seurat/outs/%s\", sample)) %>% \n#   mutate(Phase = sprintf(\"phase_%s\", Phase))\n\nPBMC <- readRDS(\"dev/PBMC.rds\")\n\nPBMC_clean_scaled <-\n  PBMC_\n  mutate(grouping = sample) %>%\n  nest(sample_df = -grouping) %>%\n  mutate(sample_df = map( sample_df,~  SCTransform(.x)))\n\nmy_features =\n  PBMC_clean_scaled$sample_df %>%\n  SelectIntegrationFeatures(nfeatures = 2000)\n\nPBMC_integrated = \n  \n  PBMC_clean_scaled$sample_df %>%\n  PrepSCTIntegration(anchor.features = my_features) %>%\n  FindIntegrationAnchors(\n    normalization.method = \"SCT\",\n    anchor.features = my_features\n  ) %>%\n  IntegrateData(normalization.method = \"SCT\")\n\nPBMC_integrated %>% saveRDS(\"dev/PBMC_integrated.rds\")"
  },
  {
    "path": "dev/workflow_figures.R",
    "content": "# Article workflow\n\nlibrary(tidyverse)\nlibrary(Seurat)\nlibrary(SingleR)\nlibrary(plotly)\nlibrary(tidyHeatmap)\nlibrary(ggalluvial)\nlibrary(ggplot2)\nlibrary(tidyseurat)\noptions(future.globals.maxSize = 50068 * 1024^2)\n\n# Use colourblind-friendly colours\nfriendly_cols <- dittoSeq::dittoColors()\n\n# Set theme\ncustom_theme <-\n  list(\n    scale_fill_manual(values = friendly_cols),\n    scale_color_manual(values = friendly_cols),\n    theme_bw() +\n      theme(\n        panel.border = element_blank(),\n        axis.line = element_line(),\n        panel.grid.major = element_line(size = 0.2),\n        panel.grid.minor = element_line(size = 0.1),\n        text = element_text(size = 9),\n        legend.position = \"bottom\",\n        strip.background = element_blank(),\n        axis.title.x = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),\n        axis.title.y = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),\n        axis.text.x = element_text(angle = 30, hjust = 1, vjust = 1)\n      )\n  )\n\n\n\nPBMC_clean_scaled_UMAP_cluster_cell_type <- readRDS(\"dev/PBMC_tidy_clean_scaled_UMAP_cluster_cell_type.rds\")\n\np1 = \n  PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  pivot_longer(\n    c(mito.fraction, S.Score, G2M.Score), \n    names_to=\"property\", \n    values_to=\"Value\"\n  ) %>%\n  mutate(property =  factor(property, levels = c(\"mito.fraction\", \"G2M.Score\", \"S.Score\"))) %>%\n  ggplot(aes(sample, Value)) + \n  geom_boxplot(outlier.size = 0.5 ) + \n  facet_wrap(~property, scales = \"free_y\" ) +\n  custom_theme +\n  theme(aspect.ratio=1)\n\np2 = \n  PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  sample_n(20000) %>%\n  ggplot(aes(UMAP_1, UMAP_2, color=seurat_clusters)) +\n  geom_point(size=0.05, alpha=0.2) +\n  custom_theme +\n  theme(aspect.ratio=1)\n\nPBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  sample_n(20000) %>%\n  plot_ly(\n    x = ~`UMAP_1`,\n    y = ~`UMAP_2`,\n    z = ~`UMAP_3`,\n    color = ~seurat_clusters,\n    colors = friendly_cols[1:24],sizes = 50, size = 1\n  )\n\nmarkers = readRDS(\"dev/PBMC_marker_df.rds\")\n\np3 = \n  PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  arrange(first.labels) %>%\n  mutate(seurat_clusters = fct_inorder(seurat_clusters)) %>%\n  join_features(features=c(\"CD3D\", \"HLA-DRB1\")) %>%\n  ggplot(aes(y=seurat_clusters , x=.abundance_SCT, fill=first.labels)) +\n  geom_density_ridges(bandwidth = 0.2) +\n  facet_wrap(~ .feature, nrow = 2) +\n  coord_flip() +\n  custom_theme\n\n# Plot heatmap\np4 = \n  PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  sample_n(2000) %>%\n  DoHeatmap(\n    features = markers$gene,\n    group.colors = friendly_cols\n  )\n\np5 = \n  PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  sample_n(1000) %>%\n  join_features(features=markers$gene) %>%\n  mutate(seurat_clusters = as.integer(seurat_clusters)) %>%\n  filter(seurat_clusters<10) %>%\n  group_by(seurat_clusters) %>%\n  \n  # Plot heatmap\n  heatmap(\n    .row = .feature,\n    .column = .cell, \n    .value = .abundance_SCT, \n    palette_grouping = list(rep(\"black\",9)), \n    palette_value = circlize::colorRamp2(c(-1.5, 0, 1.5), c(\"purple\", \"black\", \"yellow\")),\n    \n    # ComplexHeatmap parameters\n    row_gap = unit(0.1, \"mm\"), column_gap = unit(0.1, \"mm\")\n  ) %>%\n    \n  # Add annotation\n  add_tile(sample, palette = friendly_cols[1:7]) %>%\n  add_point(PC_1) \n  \np6 = \n  PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  tidyseurat::unite(\"cluster_cell_type\", c(first.labels, seurat_clusters), remove=FALSE) %>%\n  pivot_longer(\n    c(seurat_clusters, first.labels_single),\n    names_to = \"classification\", values_to = \"value\"\n  ) %>%\n  \n  ggplot(aes(x = classification, stratum = value, alluvium = cell,\n           fill = first.labels, label = value)) +\n  scale_x_discrete(expand = c(1, 1)) +\n  geom_flow() +\n  geom_stratum(alpha = .5) +\n  # geom_text(stat = \"stratum\", size = 3) +\n  geom_text_repel(stat = \"stratum\", size = 3,\n             nudge_x      = 0.05,\n             direction    = \"y\",\n             angle        = 0,\n             vjust        = 0,\n             segment.size = 0.2\n         ) +\n  scale_fill_manual(values = friendly_cols) +\n  #guides(fill = FALSE) +\n  coord_flip() +\n  theme_bw() +\n  theme(\n    panel.border = element_blank(),\n    axis.line = element_line(),\n    panel.grid.major = element_line(size = 0.2),\n    panel.grid.minor = element_line(size = 0.1),\n    text = element_text(size = 9),\n    legend.position = \"bottom\",\n    strip.background = element_blank(),\n    axis.title.x = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),\n    axis.title.y = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),\n    axis.text.x = element_text(angle = 30, hjust = 1, vjust = 1)\n  )\n\nggsave(\"dev/summary_statistics.pdf\", p1,  device = \"pdf\", width = 183/3, height = 50, units = \"mm\", useDingbats=FALSE)\nggsave(\"dev/UMAP_2D.pdf\", p2,  device = \"pdf\", width = 89, height = 100, units = \"mm\", useDingbats=FALSE)\nggsave(\"dev/violin.pdf\", p3,  device = \"pdf\", width = 89, height = 100, units = \"mm\", useDingbats=FALSE)\nsave_pdf(p5, filename = \"dev/UMAPheatmap.pdf\", width = 183+50, height = 150, units = \"mm\")\nggsave(\"dev/alluvial.pdf\", p6,  device = \"pdf\", width = 89, height = 100, units = \"mm\", useDingbats=FALSE)\n\n\n"
  },
  {
    "path": "inst/CITATION",
    "content": "citHeader(\"To cite tidyseurat in publications use:\")\n\n bibentry(\n   bibtype = \"Article\",\n   title = \"Interfacing Seurat with the R tidy universe\",\n   author = as.person(\" Stefano Mangiola [aut], Maria A Doyle [aut], Anthony T Papenfuss Anthony [aut]\"),\n   journal  = \"Bioinformatics\",\n   year = \"2021\",\n   volume   = \"btab404\",\n   publisher = \"Oxford Press\",\n   url = \"https://doi.org/10.1093/bioinformatics/btab404\"\n )\n\n\n"
  },
  {
    "path": "inst/NEWS.rd",
    "content": "\\name{NEWS}\n\\title{News for Package \\pkg{tidyseurat}}\n\n\\section{Changes in version 0.8.9}{\n\\itemize{\n    \\item CRAN fix: \\code{add_count()} now uses \\code{count(..., .add = TRUE)} instead of \\code{dplyr::add_count()}, avoiding the defunct \\code{.drop} argument (dplyr 1.0.0+).\n}}\n\n\\section{Changes in version 0.8.8}{\n\\itemize{\n    \\item Removed deprecated \\code{.drop} argument from \\code{add_count.Seurat()} to align with dplyr's API changes\n    \\item Added generic methods for \\code{add_count()} including a default method\n}}\n\n\\section{Changes in version 0.5.1, Development}{\n\\itemize{\n    \\item Change default shape parameter in join_features() and join_transcripts() from \"long\" to \"wide\", resulting in a return type of Seurat by default\n    \\item Update documentation and tests accordingly\n}}\n\n\\section{Changes in version 0.5.0, CRAN Release}{\n\\itemize{\n    \\item Rely of ttservice package for shared function with tidySingleCellExperiment to avoid clash\n    \\item Use .cell for cell column name to avoid errors when cell column is defined by the user\n}}\n"
  },
  {
    "path": "man/add_class.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/utilities.R\n\\name{add_class}\n\\alias{add_class}\n\\title{Add class to abject}\n\\usage{\nadd_class(var, name)\n}\n\\arguments{\n\\item{var}{A tibble}\n\n\\item{name}{A character name of the attribute}\n}\n\\value{\nA tibble with an additional attribute\n}\n\\description{\nAdd class to abject\n}\n\\keyword{internal}\n"
  },
  {
    "path": "man/aggregate_cells.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/methods.R\n\\name{aggregate_cells}\n\\alias{aggregate_cells}\n\\alias{aggregate_cells,Seurat-method}\n\\title{Aggregate cells}\n\\usage{\n\\S4method{aggregate_cells}{Seurat}(\n  .data,\n  .sample = NULL,\n  slot = \"data\",\n  assays = NULL,\n  aggregation_function = Matrix::rowSums,\n  ...\n)\n}\n\\arguments{\n\\item{.data}{A tidyseurat object}\n\n\\item{.sample}{A vector of variables by which cells are aggregated}\n\n\\item{slot}{The slot to which the function is applied}\n\n\\item{assays}{The assay to which the function is applied}\n\n\\item{aggregation_function}{The method of cell-feature value aggregation}\n\n\\item{...}{Used for future extendibility}\n}\n\\value{\nA tibble object\n}\n\\description{\nCombine cells into groups based on shared variables and aggregate feature counts.\n}\n\\examples{\ndata(pbmc_small)\npbmc_small_pseudo_bulk <- pbmc_small |>\n  aggregate_cells(c(groups, letter.idents), assays=\"RNA\")\n\n}\n"
  },
  {
    "path": "man/arrange.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{arrange}\n\\alias{arrange}\n\\alias{arrange.Seurat}\n\\title{Order rows using column values}\n\\usage{\n\\method{arrange}{Seurat}(.data, ..., .by_group = FALSE)\n}\n\\arguments{\n\\item{.data}{A data frame, data frame extension (e.g. a tibble), or a\nlazy data frame (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{...}{<\\code{\\link[rlang:args_data_masking]{data-masking}}> Variables, or\nfunctions of variables. Use \\code{\\link[dplyr:desc]{desc()}} to sort a variable in descending\norder.}\n\n\\item{.by_group}{If \\code{TRUE}, will sort first by grouping variable. Applies to\ngrouped data frames only.}\n}\n\\value{\nAn object of the same type as \\code{.data}. The output has the following\nproperties:\n\\itemize{\n\\item All rows appear in the output, but (usually) in a different place.\n\\item Columns are not modified.\n\\item Groups are not modified.\n\\item Data frame attributes are preserved.\n}\n}\n\\description{\n\\code{arrange()} orders the rows of a data frame by the values of selected\ncolumns.\n\nUnlike other dplyr verbs, \\code{arrange()} largely ignores grouping; you\nneed to explicitly mention grouping variables (or use  \\code{.by_group = TRUE})\nin order to group by them, and functions of variables are evaluated\nonce per data frame, not once per group.\n}\n\\details{\n\\subsection{Missing values}{\n\nUnlike base sorting with \\code{sort()}, \\code{NA} are:\n\\itemize{\n\\item always sorted to the end for local data, even when wrapped with \\code{desc()}.\n\\item treated differently for remote data, depending on the backend.\n}\n}\n}\n\\section{Methods}{\n\n\nThis function is a \\strong{generic}, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nThe following methods are currently available in loaded packages:\n\\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"arrange\")}.\n\n}\n\n\\examples{\ndata(pbmc_small)\npbmc_small |>\n    arrange(nFeature_RNA)\n\n}\n\\seealso{\nOther single table verbs: \n\\code{\\link{mutate}()},\n\\code{\\link{rename}()},\n\\code{\\link{slice}()},\n\\code{\\link{summarise}()}\n}\n\\concept{single table verbs}\n"
  },
  {
    "path": "man/as_tibble.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/tibble_methods.R\n\\name{as_tibble}\n\\alias{as_tibble}\n\\alias{as_tibble.Seurat}\n\\title{Coerce lists, matrices, and more to data frames}\n\\usage{\n\\method{as_tibble}{Seurat}(\n  x,\n  ...,\n  .name_repair = c(\"check_unique\", \"unique\", \"universal\", \"minimal\"),\n  rownames = NULL\n)\n}\n\\arguments{\n\\item{x}{A data frame, list, matrix, or other object that could reasonably be\ncoerced to a tibble.}\n\n\\item{...}{Unused, for extensibility.}\n\n\\item{.name_repair}{Treatment of problematic column names:\n\\itemize{\n\\item \\code{\"minimal\"}: No name repair or checks, beyond basic existence,\n\\item \\code{\"unique\"}: Make sure names are unique and not empty,\n\\item \\code{\"check_unique\"}: (default value), no name repair, but check they are\n\\code{unique},\n\\item \\code{\"universal\"}: Make the names \\code{unique} and syntactic\n\\item \\code{\"unique_quiet\"}: Same as \\code{\"unique\"}, but \"quiet\"\n\\item \\code{\"universal_quiet\"}: Same as \\code{\"universal\"}, but \"quiet\"\n\\item a function: apply custom name repair (e.g., \\code{.name_repair = make.names}\nfor names in the style of base R).\n\\item A purrr-style anonymous function, see \\code{\\link[rlang:as_function]{rlang::as_function()}}\n}\n\nThis argument is passed on as \\code{repair} to \\code{\\link[vctrs:vec_as_names]{vctrs::vec_as_names()}}.\nSee there for more details on these terms and the strategies used\nto enforce them.}\n\n\\item{rownames}{How to treat existing row names of a data frame or matrix:\n\\itemize{\n\\item \\code{NULL}: remove row names. This is the default.\n\\item \\code{NA}: keep row names.\n\\item A string: the name of a new column. Existing rownames are transferred\ninto this column and the \\code{row.names} attribute is deleted.\nNo name repair is applied to the new column name, even if \\code{x} already contains\na column of that name.\nUse \\code{as_tibble(rownames_to_column(...))} to safeguard against this case.\n}\n\nRead more in \\link[tibble]{rownames}.}\n}\n\\value{\n`tibble`\n}\n\\description{\n\\code{as_tibble()} turns an existing object, such as a data frame or\nmatrix, into a so-called tibble, a data frame with class \\code{\\link[tibble]{tbl_df}}. This is\nin contrast with \\code{\\link[tibble:tibble]{tibble()}}, which builds a tibble from individual columns.\n\\code{as_tibble()} is to \\code{\\link[tibble:tibble]{tibble()}} as \\code{\\link[base:as.data.frame]{base::as.data.frame()}} is to\n\\code{\\link[base:data.frame]{base::data.frame()}}.\n\n\\code{as_tibble()} is an S3 generic, with methods for:\n\\itemize{\n\\item \\code{\\link[base:data.frame]{data.frame}}: Thin wrapper around the \\code{list} method\nthat implements tibble's treatment of \\link[tibble]{rownames}.\n\\item \\code{\\link[base:matrix]{matrix}}, \\code{\\link[stats:poly]{poly}},\n\\code{\\link[stats:ts]{ts}}, \\code{\\link[base:table]{table}}\n\\item Default: Other inputs are first coerced with \\code{\\link[base:as.data.frame]{base::as.data.frame()}}.\n}\n\n\\code{as_tibble_row()} converts a vector to a tibble with one row.\nIf the input is a list, all elements must have size one.\n\n\\code{as_tibble_col()} converts a vector to a tibble with one column.\n}\n\\section{Row names}{\n\n\nThe default behavior is to silently remove row names.\n\nNew code should explicitly convert row names to a new column using the\n\\code{rownames} argument.\n\nFor existing code that relies on the retention of row names, call\n\\code{pkgconfig::set_config(\"tibble::rownames\" = NA)} in your script or in your\npackage's \\code{\\link[=.onLoad]{.onLoad()}}  function.\n\n}\n\n\\section{Life cycle}{\n\n\nUsing \\code{as_tibble()} for vectors is superseded as of version 3.0.0,\nprefer the more expressive \\code{as_tibble_row()} and\n\\code{as_tibble_col()} variants for new code.\n\n}\n\n\\examples{\ndata(pbmc_small)\npbmc_small |> as_tibble()\n\n}\n\\seealso{\n\\code{\\link[tibble:tibble]{tibble()}} constructs a tibble from individual columns. \\code{\\link[tibble:enframe]{enframe()}}\nconverts a named vector to a tibble with a column of names and column of\nvalues. Name repair is implemented using \\code{\\link[vctrs:vec_as_names]{vctrs::vec_as_names()}}.\n}\n"
  },
  {
    "path": "man/bind_rows.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{bind_rows}\n\\alias{bind_rows}\n\\alias{bind_rows.Seurat}\n\\alias{bind_cols.Seurat}\n\\alias{bind_cols}\n\\title{Efficiently bind multiple data frames by row and column}\n\\usage{\n\\method{bind_rows}{Seurat}(..., .id = NULL, add.cell.ids = NULL)\n\n\\method{bind_cols}{Seurat}(..., .id = NULL)\n}\n\\arguments{\n\\item{...}{Data frames to combine.\n\n  Each argument can either be a data frame, a list that could be a data\n  frame, or a list of data frames.\n\n  When row-binding, columns are matched by name, and any missing\n  columns will be filled with NA.\n\n  When column-binding, rows are matched by position, so all data\n  frames must have the same number of rows. To match by value, not\n  position, see mutate-joins.}\n\n\\item{.id}{Data frame identifier.\n\n  When `.id` is supplied, a new column of identifiers is\n  created to link each row to its original data frame. The labels\n  are taken from the named arguments to `bind_rows()`. When a\n  list of data frames is supplied, the labels are taken from the\n  names of the list. If no names are found a numeric sequence is\n  used instead.}\n\n\\item{add.cell.ids}{from Seurat 3.0 A character vector of length(x = c(x, y)). Appends the corresponding values to the start of each objects' cell names.}\n}\n\\value{\n`bind_rows()` and `bind_cols()` return the same type as\n  the first input, either a data frame, `tbl_df`, or `grouped_df`.\n\n`bind_rows()` and `bind_cols()` return the same type as\n  the first input, either a data frame, `tbl_df`, or `grouped_df`.\n}\n\\description{\nThis is an efficient implementation of the common pattern of\n`do.call(rbind, dfs)` or `do.call(cbind, dfs)` for binding many\ndata frames into one.\n\nThis is an efficient implementation of the common pattern of\n`do.call(rbind, dfs)` or `do.call(cbind, dfs)` for binding many\ndata frames into one.\n}\n\\details{\nThe output of `bind_rows()` will contain a column if that column\nappears in any of the inputs.\n\nThe output of `bind_rows()` will contain a column if that column\nappears in any of the inputs.\n}\n\\examples{\ndata(pbmc_small)\ntt <- pbmc_small\nttservice::bind_rows(tt, tt)\n\ntt_bind <- tt |> select(nCount_RNA ,nFeature_RNA)\ntt |> ttservice::bind_cols(tt_bind)\n\n}\n"
  },
  {
    "path": "man/cell_type_df.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/data.R\n\\docType{data}\n\\name{cell_type_df}\n\\alias{cell_type_df}\n\\title{Cell types of 80 PBMC single cells}\n\\format{\nA tibble containing 80 rows and 2 columns.\n  Cells are a subsample of the Peripheral Blood Mononuclear Cells (PBMC) \n  dataset of 2,700 single cell. Cell types were identified with SingleR.\n\\describe{\n  \\item{cell}{cell identifier, barcode}\n  \\item{first.labels}{cell type}\n}\n}\n\\source{\n\\url{https://satijalab.org/seurat/v3.1/pbmc3k_tutorial.html}\n}\n\\usage{\ndata(cell_type_df)\n}\n\\value{\n`tibble`\n}\n\\description{\nA dataset containing the barcodes and cell types of 80 PBMC single cells.\n}\n\\keyword{datasets}\n"
  },
  {
    "path": "man/count.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{count}\n\\alias{count}\n\\alias{count.Seurat}\n\\alias{add_count}\n\\alias{add_count.default}\n\\alias{add_count.Seurat}\n\\title{Count observations by group}\n\\usage{\n\\method{count}{Seurat}(\n  x,\n  ...,\n  wt = NULL,\n  sort = FALSE,\n  name = NULL,\n  .drop = group_by_drop_default(x)\n)\n\nadd_count(x, ..., wt = NULL, sort = FALSE, name = NULL)\n\n\\method{add_count}{default}(x, ..., wt = NULL, sort = FALSE, name = NULL)\n\n\\method{add_count}{Seurat}(x, ..., wt = NULL, sort = FALSE, name = NULL)\n}\n\\arguments{\n\\item{x}{A data frame, data frame extension (e.g. a tibble), or a\nlazy data frame (e.g. from dbplyr or dtplyr).}\n\n\\item{...}{<[`data-masking`][dplyr_data_masking]> Variables to group by.}\n\n\\item{wt}{<[`data-masking`][dplyr_data_masking]> Frequency weights.\n  Can be `NULL` or a variable:\n\n  * If `NULL` (the default), counts the number of rows in each group.\n  * If a variable, computes `sum(wt)` for each group.}\n\n\\item{sort}{If `TRUE`, will show the largest groups at the top.}\n\n\\item{name}{The name of the new column in the output.\n\n  If omitted, it will default to `n`. If there's already a column called `n`,\n  it will error, and require you to specify the name.}\n\n\\item{.drop}{For `count()`: if `FALSE` will include counts for empty groups\n(i.e. for levels of factors that don't exist in the data).}\n}\n\\value{\nAn object of the same type as `.data`. `count()` and `add_count()`\ngroup transiently, so the output has the same groups as the input.\n}\n\\description{\n`count()` lets you quickly count the unique values of one or more variables:\n`df %>% count(a, b)` is roughly equivalent to\n`df %>% group_by(a, b) %>% summarise(n = n())`.\n`count()` is paired with `tally()`, a lower-level helper that is equivalent\nto `df %>% summarise(n = n())`. Supply `wt` to perform weighted counts,\nswitching the summary from `n = n()` to `n = sum(wt)`.\n\n`add_count()` and `add_tally()` are equivalents to `count()` and `tally()`\nbut use `mutate()` instead of `summarise()` so that they add a new column\nwith group-wise counts.\n}\n\\examples{\ndata(pbmc_small)\npbmc_small |> count(groups)\n    \n}\n"
  },
  {
    "path": "man/distinct.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{distinct}\n\\alias{distinct}\n\\alias{distinct.Seurat}\n\\title{Keep distinct/unique rows}\n\\usage{\n\\method{distinct}{Seurat}(.data, ..., .keep_all = FALSE)\n}\n\\arguments{\n\\item{.data}{A data frame, data frame extension (e.g. a tibble), or a\nlazy data frame (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{...}{<\\code{\\link[rlang:args_data_masking]{data-masking}}> Optional variables to\nuse when determining uniqueness. If there are multiple rows for a given\ncombination of inputs, only the first row will be preserved. If omitted,\nwill use all variables in the data frame.}\n\n\\item{.keep_all}{If \\code{TRUE}, keep all variables in \\code{.data}.\nIf a combination of \\code{...} is not distinct, this keeps the\nfirst row of values.}\n}\n\\value{\nAn object of the same type as \\code{.data}. The output has the following\nproperties:\n\\itemize{\n\\item Rows are a subset of the input but appear in the same order.\n\\item Columns are not modified if \\code{...} is empty or \\code{.keep_all} is \\code{TRUE}.\nOtherwise, \\code{distinct()} first calls \\code{mutate()} to create new columns.\n\\item Groups are not modified.\n\\item Data frame attributes are preserved.\n}\n}\n\\description{\nKeep only unique/distinct rows from a data frame. This is similar\nto \\code{\\link[=unique.data.frame]{unique.data.frame()}} but considerably faster.\n}\n\\section{Methods}{\n\n\nThis function is a \\strong{generic}, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nThe following methods are currently available in loaded packages:\n\\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"distinct\")}.\n\n}\n\n\\examples{\ndata(\"pbmc_small\")\npbmc_small |> distinct(groups)\n\n}\n"
  },
  {
    "path": "man/drop_class.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/utilities.R\n\\name{drop_class}\n\\alias{drop_class}\n\\title{Remove class to abject}\n\\usage{\ndrop_class(var, name)\n}\n\\arguments{\n\\item{var}{A tibble}\n\n\\item{name}{A character name of the class}\n}\n\\value{\nA tibble with an additional attribute\n}\n\\description{\nRemove class to abject\n}\n\\keyword{internal}\n"
  },
  {
    "path": "man/extract.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/tidyr_methods.R\n\\name{extract}\n\\alias{extract}\n\\alias{extract.Seurat}\n\\title{Extract a character column into multiple columns using regular\nexpression groups}\n\\usage{\n\\method{extract}{Seurat}(\n  data,\n  col,\n  into,\n  regex = \"([[:alnum:]]+)\",\n  remove = TRUE,\n  convert = FALSE,\n  ...\n)\n}\n\\arguments{\n\\item{data}{A data frame.}\n\n\\item{col}{<\\code{\\link[tidyr:tidyr_tidy_select]{tidy-select}}> Column to expand.}\n\n\\item{into}{Names of new variables to create as character vector.\nUse \\code{NA} to omit the variable in the output.}\n\n\\item{regex}{A string representing a regular expression used to extract the\ndesired values. There should be one group (defined by \\verb{()}) for each\nelement of \\code{into}.}\n\n\\item{remove}{If \\code{TRUE}, remove input column from output data frame.}\n\n\\item{convert}{If \\code{TRUE}, will run \\code{\\link[=type.convert]{type.convert()}} with\n\\code{as.is = TRUE} on new columns. This is useful if the component\ncolumns are integer, numeric or logical.\n\nNB: this will cause string \\code{\"NA\"}s to be converted to \\code{NA}s.}\n\n\\item{...}{Additional arguments passed on to methods.}\n}\n\\value{\n`tidyseurat`\n}\n\\description{\n\\ifelse{html}{\\href{https://lifecycle.r-lib.org/articles/stages.html#superseded}{\\figure{lifecycle-superseded.svg}{options: alt='[Superseded]'}}}{\\strong{[Superseded]}}\n\n\\code{extract()} has been superseded in favour of \\code{\\link[tidyr:separate_wider_regex]{separate_wider_regex()}}\nbecause it has a more polished API and better handling of problems.\nSuperseded functions will not go away, but will only receive critical bug\nfixes.\n\nGiven a regular expression with capturing groups, \\code{extract()} turns\neach group into a new column. If the groups don't match, or the input\nis NA, the output will be NA.\n}\n\\examples{\ndata(pbmc_small)\npbmc_small |>\n  extract(groups, \n    into=\"g\", \n    regex=\"g([0-9])\", \n    convert=TRUE)\n\n}\n\\seealso{\n\\code{\\link[tidyr:separate]{separate()}} to split up by a separator.\n}\n"
  },
  {
    "path": "man/filter.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{filter}\n\\alias{filter}\n\\alias{filter.Seurat}\n\\title{Keep or drop rows that match a condition}\n\\usage{\n\\method{filter}{Seurat}(.data, ..., .preserve = FALSE)\n}\n\\arguments{\n\\item{.data}{A data frame, data frame extension (e.g. a tibble), or a\nlazy data frame (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{...}{<\\code{\\link[rlang:args_data_masking]{data-masking}}> Expressions that\nreturn a logical vector, defined in terms of the variables in \\code{.data}. If\nmultiple expressions are included, they are combined with the \\code{&} operator.\nTo combine expressions using \\code{|} instead, wrap them in \\code{\\link[dplyr:when_any]{when_any()}}. Only\nrows for which all expressions evaluate to \\code{TRUE} are kept (for \\code{filter()})\nor dropped (for \\code{filter_out()}).}\n\n\\item{.preserve}{Relevant when the \\code{.data} input is grouped. If \\code{.preserve = FALSE} (the default), the grouping structure is recalculated based on the\nresulting data, otherwise the grouping is kept as is.}\n}\n\\value{\nAn object of the same type as \\code{.data}. The output has the following\nproperties:\n\\itemize{\n\\item Rows are a subset of the input, but appear in the same order.\n\\item Columns are not modified.\n\\item The number of groups may be reduced (if \\code{.preserve} is not \\code{TRUE}).\n\\item Data frame attributes are preserved.\n}\n}\n\\description{\nThese functions are used to subset a data frame, applying the expressions in\n\\code{...} to determine which rows should be kept (for \\code{filter()}) or dropped (\nfor \\code{filter_out()}).\n\nMultiple conditions can be supplied separated by a comma. These will be\ncombined with the \\code{&} operator. To combine comma separated conditions using\n\\code{|} instead, wrap them in \\code{\\link[dplyr:when_any]{when_any()}}.\n\nBoth \\code{filter()} and \\code{filter_out()} treat \\code{NA} like \\code{FALSE}. This subtle\nbehavior can impact how you write your conditions when missing values are\ninvolved. See the section on \\verb{Missing values} for important details and\nexamples.\n}\n\\section{Missing values}{\n\n\n\nBoth \\code{filter()} and \\code{filter_out()} treat \\code{NA} like \\code{FALSE}. This results in\nthe following behavior:\n\\itemize{\n\\item \\code{filter()} \\emph{drops} both \\code{NA} and \\code{FALSE}.\n\\item \\code{filter_out()} \\emph{keeps} both \\code{NA} and \\code{FALSE}.\n}\n\nThis means that \\verb{filter(data, <conditions>) + filter_out(data, <conditions>)}\ncaptures every row within \\code{data} exactly once.\n\nThe \\code{NA} handling of these functions has been designed to match your\n\\emph{intent}. When your intent is to keep rows, use \\code{filter()}. When your intent\nis to drop rows, use \\code{filter_out()}.\n\nFor example, if your goal with this \\code{cars} data is to \"drop rows where the\n\\code{class} is suv\", then you might write this in one of two ways:\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{cars <- tibble(class = c(\"suv\", NA, \"coupe\"))\ncars\n#> # A tibble: 3 x 1\n#>   class\n#>   <chr>\n#> 1 suv  \n#> 2 <NA> \n#> 3 coupe\n}\\if{html}{\\out{</div>}}\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{cars |> filter(class != \"suv\")\n#> # A tibble: 1 x 1\n#>   class\n#>   <chr>\n#> 1 coupe\n}\\if{html}{\\out{</div>}}\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{cars |> filter_out(class == \"suv\")\n#> # A tibble: 2 x 1\n#>   class\n#>   <chr>\n#> 1 <NA> \n#> 2 coupe\n}\\if{html}{\\out{</div>}}\n\nNote how \\code{filter()} drops the \\code{NA} rows even though our goal was only to drop\n\\code{\"suv\"} rows, but \\code{filter_out()} matches our intuition.\n\nTo generate the correct result with \\code{filter()}, you'd need to use:\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{cars |> filter(class != \"suv\" | is.na(class))\n#> # A tibble: 2 x 1\n#>   class\n#>   <chr>\n#> 1 <NA> \n#> 2 coupe\n}\\if{html}{\\out{</div>}}\n\nThis quickly gets unwieldy when multiple conditions are involved.\n\nIn general, if you find yourself:\n\\itemize{\n\\item Using \"negative\" operators like \\code{!=} or \\code{!}\n\\item Adding in \\code{NA} handling like \\verb{| is.na(col)} or \\verb{& !is.na(col)}\n}\n\nthen you should consider if swapping to the other filtering variant would\nmake your conditions simpler.\n\\subsection{Comparison to base subsetting}{\n\nBase subsetting with \\code{[} doesn't treat \\code{NA} like \\code{TRUE} or \\code{FALSE}. Instead,\nit generates a fully missing row, which is different from how both \\code{filter()}\nand \\code{filter_out()} work.\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{cars <- tibble(class = c(\"suv\", NA, \"coupe\"), mpg = c(10, 12, 14))\ncars\n#> # A tibble: 3 x 2\n#>   class   mpg\n#>   <chr> <dbl>\n#> 1 suv      10\n#> 2 <NA>     12\n#> 3 coupe    14\n}\\if{html}{\\out{</div>}}\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{cars[cars$class == \"suv\",]\n#> # A tibble: 2 x 2\n#>   class   mpg\n#>   <chr> <dbl>\n#> 1 suv      10\n#> 2 <NA>     NA\n\ncars |> filter(class == \"suv\")\n#> # A tibble: 1 x 2\n#>   class   mpg\n#>   <chr> <dbl>\n#> 1 suv      10\n}\\if{html}{\\out{</div>}}\n}\n\n}\n\n\\section{Useful filter functions}{\n\n\n\nThere are many functions and operators that are useful when constructing the\nexpressions used to filter the data:\n\\itemize{\n\\item \\code{\\link{==}}, \\code{\\link{>}}, \\code{\\link{>=}} etc\n\\item \\code{\\link{&}}, \\code{\\link{|}}, \\code{\\link{!}}, \\code{\\link[=xor]{xor()}}\n\\item \\code{\\link[=is.na]{is.na()}}\n\\item \\code{\\link[dplyr:between]{between()}}, \\code{\\link[dplyr:near]{near()}}\n\\item \\code{\\link[dplyr:when_any]{when_any()}}, \\code{\\link[dplyr:when_all]{when_all()}}\n}\n\n}\n\n\\section{Grouped tibbles}{\n\n\n\nBecause filtering expressions are computed within groups, they may yield\ndifferent results on grouped tibbles. This will be the case as soon as an\naggregating, lagging, or ranking function is involved. Compare this ungrouped\nfiltering:\n\n\\if{html}{\\out{<div class=\"sourceCode\">}}\\preformatted{starwars |> filter(mass > mean(mass, na.rm = TRUE))\n}\\if{html}{\\out{</div>}}\n\nWith the grouped equivalent:\n\n\\if{html}{\\out{<div class=\"sourceCode\">}}\\preformatted{starwars |> filter(mass > mean(mass, na.rm = TRUE), .by = gender)\n}\\if{html}{\\out{</div>}}\n\nIn the ungrouped version, \\code{filter()} compares the value of \\code{mass} in each row\nto the global average (taken over the whole data set), keeping only the rows\nwith \\code{mass} greater than this global average. In contrast, the grouped\nversion calculates the average mass separately for each \\code{gender} group, and\nkeeps rows with \\code{mass} greater than the relevant within-gender average.\n\n}\n\n\\section{Methods}{\n\n\n\nThis function is a \\strong{generic}, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nThe following methods are currently available in loaded packages:\n\\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"filter\")}.\n\n}\n\n\\examples{\ndata(\"pbmc_small\")\npbmc_small |>  filter(groups == \"g1\")\n\n# Learn more in ?dplyr_eval\n\n}\n\\seealso{\nOther single table verbs: \n\\code{\\link[dplyr]{arrange}()},\n\\code{\\link[dplyr]{mutate}()},\n\\code{\\link[dplyr]{reframe}()},\n\\code{\\link[dplyr]{rename}()},\n\\code{\\link[dplyr]{select}()},\n\\code{\\link[dplyr]{slice}()},\n\\code{\\link[dplyr]{summarise}()}\n}\n"
  },
  {
    "path": "man/formatting.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/print_method.R\n\\name{formatting}\n\\alias{formatting}\n\\alias{print.Seurat}\n\\alias{print}\n\\title{Printing tibbles}\n\\usage{\n\\method{print}{Seurat}(x, ..., n = NULL, width = NULL, n_extra = NULL)\n}\n\\arguments{\n\\item{x}{Object to format or print.}\n\n\\item{...}{Passed on to \\code{\\link[pillar:tbl_format_setup]{tbl_format_setup()}}.}\n\n\\item{n}{Number of rows to show. If \\code{NULL}, the default, will print all rows\nif less than the \\code{print_max} \\link[pillar:pillar_options]{option}.\nOtherwise, will print as many rows as specified by the\n\\code{print_min} \\link[pillar:pillar_options]{option}.}\n\n\\item{width}{Width of text output to generate. This defaults to \\code{NULL}, which\nmeans use the \\code{width} \\link[pillar:pillar_options]{option}.}\n\n\\item{n_extra}{Number of extra columns to print abbreviated information for,\nif the width is too small for the entire tibble. If `NULL`, the default,\nwill print information about at most `tibble.max_extra_cols` extra columns.}\n}\n\\value{\nPrints a message to the console describing\n  the contents of the `tidyseurat`.\n}\n\\description{\nOne of the main features of the \\code{tbl_df} class is the printing:\n\\itemize{\n\\item Tibbles only print as many rows and columns as fit on one screen,\nsupplemented by a summary of the remaining rows and columns.\n\\item Tibble reveals the type of each column, which keeps the user informed about\nwhether a variable is, e.g., \\verb{<chr>} or \\verb{<fct>} (character versus factor).\nSee \\code{vignette(\"types\")} for an overview of common\ntype abbreviations.\n}\n\nPrinting can be tweaked for a one-off call by calling \\code{print()} explicitly\nand setting arguments like \\code{n} and \\code{width}. More persistent control is\navailable by setting the options described in \\link[pillar:pillar_options]{pillar::pillar_options}.\nSee also \\code{vignette(\"digits\")} for a comparison to base options,\nand \\code{vignette(\"numbers\")} that showcases \\code{\\link[tibble:num]{num()}} and \\code{\\link[tibble:char]{char()}}\nfor creating columns with custom formatting options.\n\nAs of tibble 3.1.0, printing is handled entirely by the \\pkg{pillar} package.\nIf you implement a package that extends tibble,\nthe printed output can be customized in various ways.\nSee \\code{vignette(\"extending\", package = \"pillar\")} for details,\nand \\link[pillar:pillar_options]{pillar::pillar_options} for options that control the display in the console.\n}\n\\examples{\ndata(pbmc_small)\nprint(pbmc_small)\n\n}\n"
  },
  {
    "path": "man/fragments/intro.Rmd",
    "content": "\n**Brings Seurat to the tidyverse!**\n\nwebsite: [stemangiola.github.io/tidyseurat/](https://stemangiola.github.io/tidyseurat/)\n\nPlease also have a look at\n\n- [tidyseurat](https://stemangiola.github.io/tidyseurat/) for tidy single-cell RNA sequencing analysis\n- [tidySummarizedExperiment](https://tidyomics.github.io/tidySummarizedExperiment/) for tidy bulk RNA sequencing analysis\n- [tidybulk](https://tidyomics.github.io/tidybulk/) for tidy bulk RNA-seq analysis\n- [tidygate](https://github.com/stemangiola/tidygate/) for adding custom gate information to your tibble\n- [tidyHeatmap](https://stemangiola.github.io/tidyHeatmap/) for heatmaps produced with tidy principles\n\n\n```{r, echo=FALSE, include=FALSE, }\nlibrary(knitr)\nknitr::opts_chunk$set(warning = FALSE, message = FALSE)\n```\n\n![visual cue](`r visual_cue`)\n\n# Introduction\n\ntidyseurat provides a bridge between the Seurat single-cell package [@butler2018integrating; @stuart2019comprehensive] and the tidyverse [@wickham2019welcome]. It creates an invisible layer that enables viewing the\nSeurat object as a tidyverse tibble, and provides Seurat-compatible *dplyr*, *tidyr*, *ggplot* and *plotly* functions.\n\n\n## Functions/utilities available\n\nSeurat-compatible Functions | Description\n------------ | -------------\n`all` | \n\ntidyverse Packages | Description\n------------ | -------------\n`dplyr` | All `dplyr` APIs like for any tibble\n`tidyr` | All `tidyr` APIs like for any tibble\n`ggplot2` | `ggplot` like for any tibble\n`plotly` | `plot_ly` like for any tibble\n\nUtilities | Description\n------------ | -------------\n`tidy` | Add `tidyseurat` invisible layer over a Seurat object\n`as_tibble` | Convert cell-wise information to a `tbl_df`\n`join_features` | Add feature-wise information, returns a `tbl_df`\n`aggregate_cells`| Aggregate cell gene-transcription abundance as pseudobulk tissue                  |\n\n## Installation\n\nFrom CRAN\n```{r eval=FALSE}\ninstall.packages(\"tidyseurat\")\n```\n\nFrom Github (development)\n```{r, eval=FALSE}\ndevtools::install_github(\"stemangiola/tidyseurat\")\n```\n\n```{r}\nlibrary(dplyr)\nlibrary(tidyr)\nlibrary(purrr)\nlibrary(magrittr)\nlibrary(ggplot2)\nlibrary(Seurat)\nlibrary(tidyseurat)\n```\n\n\n## Create `tidyseurat`, the best of both worlds!\n\nThis is a seurat object but it is evaluated as tibble. So it is fully compatible both with Seurat and tidyverse APIs.\n\n```{r}\npbmc_small = SeuratObject::pbmc_small\n```\n\n**It looks like a tibble**\n\n```{r}\npbmc_small\n```\n\n**But it is a Seurat object after all**\n\n```{r}\npbmc_small@assays\n```\n\n# Preliminary plots\n\nSet colours and theme for plots.\n\n```{r}\n# Use colourblind-friendly colours\nfriendly_cols <- c(\"#88CCEE\", \"#CC6677\", \"#DDCC77\", \"#117733\", \"#332288\", \"#AA4499\", \"#44AA99\", \"#999933\", \"#882255\", \"#661100\", \"#6699CC\")\n\n# Set theme\nmy_theme <-\n  list(\n    scale_fill_manual(values = friendly_cols),\n    scale_color_manual(values = friendly_cols),\n    theme_bw() +\n      theme(\n        panel.border = element_blank(),\n        axis.line = element_line(),\n        panel.grid.major = element_line(size = 0.2),\n        panel.grid.minor = element_line(size = 0.1),\n        text = element_text(size = 12),\n        legend.position = \"bottom\",\n        aspect.ratio = 1,\n        strip.background = element_blank(),\n        axis.title.x = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),\n        axis.title.y = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10))\n      )\n  )\n```\n\nWe can treat `pbmc_small` effectively as a normal tibble for plotting.\n\nHere we plot number of features per cell.\n\n```{r plot1}\npbmc_small %>%\n  ggplot(aes(nFeature_RNA, fill = groups)) +\n  geom_histogram() +\n  my_theme\n```\n\nHere we plot total features per cell.\n\n```{r plot2}\npbmc_small %>%\n  ggplot(aes(groups, nCount_RNA, fill = groups)) +\n  geom_boxplot(outlier.shape = NA) +\n  geom_jitter(width = 0.1) +\n  my_theme\n```\n\nHere we plot abundance of two features for each group.\n\n```{r}\npbmc_small %>%\n  join_features(features = c(\"HLA-DRA\", \"LYZ\"), shape = \"long\") %>%\n  ggplot(aes(groups, .abundance_RNA + 1, fill = groups)) +\n  geom_boxplot(outlier.shape = NA) +\n  geom_jitter(aes(size = nCount_RNA), alpha = 0.5, width = 0.2) +\n  scale_y_log10() +\n  my_theme\n```\n\n# Preprocess the dataset\n\nAlso you can treat the object as Seurat object and proceed with data processing.\n\n```{r preprocess}\npbmc_small_pca <-\n  pbmc_small %>%\n  SCTransform(verbose = FALSE) %>%\n  FindVariableFeatures(verbose = FALSE) %>%\n  RunPCA(verbose = FALSE)\n\npbmc_small_pca\n```\n\n\nIf a tool is not included in the tidyseurat collection, we can use `as_tibble` to permanently convert `tidyseurat` into tibble.\n\n```{r pc_plot}\npbmc_small_pca %>%\n  as_tibble() %>%\n  select(contains(\"PC\"), everything()) %>%\n  GGally::ggpairs(columns = 1:5, ggplot2::aes(colour = groups)) +\n  my_theme\n```\n\n# Identify clusters\n\nWe proceed with cluster identification with Seurat.\n\n```{r cluster}\npbmc_small_cluster <-\n  pbmc_small_pca %>%\n  FindNeighbors(verbose = FALSE) %>%\n  FindClusters(method = \"igraph\", verbose = FALSE)\n\npbmc_small_cluster\n```\n\nNow we can interrogate the object as if it was a regular tibble data frame.\n\n```{r cluster count}\npbmc_small_cluster %>%\n  count(groups, seurat_clusters)\n```\n\nWe can identify cluster markers using Seurat.\n\n<!-- If this is Seurat v4, comment out the v3 markers -->\n\n`r if (packageVersion(\"Seurat\") >= package_version(\"4.0.0\")) {\"<!--\"}`\n\n```{r markers_v3, eval=(packageVersion(\"Seurat\") < package_version(\"4.0.0\"))}\n# Identify top 10 markers per cluster\nmarkers <-\n  pbmc_small_cluster %>%\n  mutate(orig.ident = seurat_clusters) %>% \n  FindAllMarkers(only.pos = TRUE) %>%\n  group_by(cluster) %>%\n  top_n(10, avg_logFC)\n\n# Plot heatmap\npbmc_small_cluster %>%\n  DoHeatmap(\n    features = markers$gene,\n    group.colors = friendly_cols\n  )\n```\n\n`r if (packageVersion(\"Seurat\") >= package_version(\"4.0.0\")) {\"-->\"}`\n\n<!-- If this is Seurat v3, comment out the v4 markers -->\n\n`r if (packageVersion(\"Seurat\") < package_version(\"4.0.0\")) {\"<!--\"}`\n\n```{r markers_v4, eval=FALSE}\n# Identify top 10 markers per cluster\nmarkers <-\n  pbmc_small_cluster %>%\n  FindAllMarkers(only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25) %>%\n  group_by(cluster) %>%\n  top_n(10, avg_log2FC)\n\n# Plot heatmap\npbmc_small_cluster %>%\n  DoHeatmap(\n    features = markers$gene,\n    group.colors = friendly_cols\n  )\n```\n\n`r if (packageVersion(\"Seurat\") < package_version(\"4.0.0\")) {\"-->\"}`\n\n# Reduce dimensions\n\nWe can calculate the first 3 UMAP dimensions using the Seurat framework.\n\n```{r umap, eval=FALSE}\npbmc_small_UMAP <-\n  pbmc_small_cluster %>%\n  RunUMAP(reduction = \"pca\", dims = 1:15, n.components = 3L)\n```\n\nAnd we can plot them using 3D plot using plotly.\n\n```{r umap plot, eval=FALSE}\npbmc_small_UMAP %>%\n  plot_ly(\n    x = ~`UMAP_1`,\n    y = ~`UMAP_2`,\n    z = ~`UMAP_3`,\n    color = ~seurat_clusters,\n    colors = friendly_cols[1:4]\n  )\n```\n![screenshot plotly](`r screenshot`)\n\n\n## Cell type prediction\n\nWe can infer cell type identities using *SingleR* [@aran2019reference] and manipulate the output using tidyverse.\n\n```{r eval=FALSE}\n# Get cell type reference data\nblueprint <- celldex::BlueprintEncodeData()\n\n# Infer cell identities\ncell_type_df <-\n  GetAssayData(pbmc_small_UMAP, slot = 'counts', assay = \"SCT\") %>%\n  log1p() %>%\n  Matrix::Matrix(sparse = TRUE) %>%\n  SingleR::SingleR(\n    ref = blueprint,\n    labels = blueprint$label.main,\n    method = \"single\"\n  ) %>%\n  as.data.frame() %>%\n  as_tibble(rownames = \"cell\") %>%\n  select(cell, first.labels)\n```\n\n```{r, eval=FALSE}\n# Join UMAP and cell type info\npbmc_small_cell_type <-\n  pbmc_small_UMAP %>%\n  left_join(cell_type_df, by = \"cell\")\n\n# Reorder columns\npbmc_small_cell_type %>%\n  select(cell, first.labels, everything())\n```\n\nWe can easily summarise the results. For example, we can see how cell type classification overlaps with cluster classification.\n\n```{r, eval=FALSE}\npbmc_small_cell_type %>%\n  count(seurat_clusters, first.labels)\n```\n\nWe can easily reshape the data for building information-rich faceted plots.\n\n```{r eval=FALSE}\npbmc_small_cell_type %>%\n\n  # Reshape and add classifier column\n  pivot_longer(\n    cols = c(seurat_clusters, first.labels),\n    names_to = \"classifier\", values_to = \"label\"\n  ) %>%\n\n  # UMAP plots for cell type and cluster\n  ggplot(aes(UMAP_1, UMAP_2, color = label)) +\n  geom_point() +\n  facet_wrap(~classifier) +\n  my_theme\n```\n\nWe can easily plot gene correlation per cell category, adding multi-layer annotations.\n\n```{r eval=FALSE}\npbmc_small_cell_type %>%\n\n  # Add some mitochondrial abundance values\n  mutate(mitochondrial = rnorm(n())) %>%\n\n  # Plot correlation\n  join_features(features = c(\"CST3\", \"LYZ\"), shape = \"wide\") %>%\n  ggplot(aes(CST3 + 1, LYZ + 1, color = groups, size = mitochondrial)) +\n  geom_point() +\n  facet_wrap(~first.labels, scales = \"free\") +\n  scale_x_log10() +\n  scale_y_log10() +\n  my_theme\n```\n\n#  Nested analyses\n\nA powerful tool we can use with tidyseurat is `nest`. We can easily perform independent analyses on subsets of the dataset. First we classify cell types in lymphoid and myeloid; then, nest based on the new classification\n\n```{r eval=FALSE}\npbmc_small_nested <-\n  pbmc_small_cell_type %>%\n  filter(first.labels != \"Erythrocytes\") %>%\n  mutate(cell_class = if_else(`first.labels` %in% c(\"Macrophages\", \"Monocytes\"), \"myeloid\", \"lymphoid\")) %>%\n  nest(data = -cell_class)\n\npbmc_small_nested\n```\n\nNow we can independently for the lymphoid and myeloid subsets (i) find variable features, (ii) reduce dimensions, and (iii) cluster using both tidyverse and Seurat seamlessly.\n\n```{r eval=FALSE}\npbmc_small_nested_reanalysed <-\n  pbmc_small_nested %>%\n  mutate(data = map(\n    data, ~ .x %>%\n      FindVariableFeatures(verbose = FALSE) %>%\n      RunPCA(npcs = 10, verbose = FALSE) %>%\n      FindNeighbors(verbose = FALSE) %>%\n      FindClusters(method = \"igraph\", verbose = FALSE) %>%\n      RunUMAP(reduction = \"pca\", dims = 1:10, n.components = 3L, verbose = FALSE)\n  ))\n\npbmc_small_nested_reanalysed\n```\n\nNow we can unnest and plot the new classification.\n\n```{r eval=FALSE}\npbmc_small_nested_reanalysed %>%\n\n  # Convert to tibble otherwise Seurat drops reduced dimensions when unifying data sets.\n  mutate(data = map(data, ~ .x %>% as_tibble())) %>%\n  unnest(data) %>%\n\n  # Define unique clusters\n  unite(\"cluster\", c(cell_class, seurat_clusters), remove = FALSE) %>%\n\n  # Plotting\n  ggplot(aes(UMAP_1, UMAP_2, color = cluster)) +\n  geom_point() +\n  facet_wrap(~cell_class) +\n  my_theme\n```\n\n#  Aggregating cells \n\nSometimes, it is necessary to aggregate the gene-transcript abundance from a group of cells into a single value. For example, when comparing groups of cells across different samples with fixed-effect models.\n\nIn tidyseurat, cell aggregation can be achieved using the `aggregate_cells` function.\n \n \n```{r, eval=FALSE}\npbmc_small %>%\n  aggregate_cells(groups, assays = \"RNA\")\n```\n\n   "
  },
  {
    "path": "man/full_join.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{full_join}\n\\alias{full_join}\n\\alias{full_join.Seurat}\n\\title{Mutating joins}\n\\usage{\n\\method{full_join}{Seurat}(x, y, by = NULL, copy = FALSE, suffix = c(\".x\", \".y\"), ...)\n}\n\\arguments{\n\\item{x, y}{A pair of data frames, data frame extensions (e.g. a tibble), or\nlazy data frames (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{by}{A join specification created with \\code{\\link[dplyr:join_by]{join_by()}}, or a character\nvector of variables to join by.\n\nIf \\code{NULL}, the default, \\verb{*_join()} will perform a natural join, using all\nvariables in common across \\code{x} and \\code{y}. A message lists the variables so\nthat you can check they're correct; suppress the message by supplying \\code{by}\nexplicitly.\n\nTo join on different variables between \\code{x} and \\code{y}, use a \\code{\\link[dplyr:join_by]{join_by()}}\nspecification. For example, \\code{join_by(a == b)} will match \\code{x$a} to \\code{y$b}.\n\nTo join by multiple variables, use a \\code{\\link[dplyr:join_by]{join_by()}} specification with\nmultiple expressions. For example, \\code{join_by(a == b, c == d)} will match\n\\code{x$a} to \\code{y$b} and \\code{x$c} to \\code{y$d}. If the column names are the same between\n\\code{x} and \\code{y}, you can shorten this by listing only the variable names, like\n\\code{join_by(a, c)}.\n\n\\code{\\link[dplyr:join_by]{join_by()}} can also be used to perform inequality, rolling, and overlap\njoins. See the documentation at \\link[dplyr:join_by]{?join_by} for details on\nthese types of joins.\n\nFor simple equality joins, you can alternatively specify a character vector\nof variable names to join by. For example, \\code{by = c(\"a\", \"b\")} joins \\code{x$a}\nto \\code{y$a} and \\code{x$b} to \\code{y$b}. If variable names differ between \\code{x} and \\code{y},\nuse a named character vector like \\code{by = c(\"x_a\" = \"y_a\", \"x_b\" = \"y_b\")}.\n\nTo perform a cross-join, generating all combinations of \\code{x} and \\code{y}, see\n\\code{\\link[dplyr:cross_join]{cross_join()}}.}\n\n\\item{copy}{If \\code{x} and \\code{y} are not from the same data source,\nand \\code{copy} is \\code{TRUE}, then \\code{y} will be copied into the\nsame src as \\code{x}.  This allows you to join tables across srcs, but\nit is a potentially expensive operation so you must opt into it.}\n\n\\item{suffix}{If there are non-joined duplicate variables in \\code{x} and\n\\code{y}, these suffixes will be added to the output to disambiguate them.\nShould be a character vector of length 2.}\n\n\\item{...}{Other parameters passed onto methods.}\n}\n\\value{\nAn object of the same type as \\code{x} (including the same groups). The order of\nthe rows and columns of \\code{x} is preserved as much as possible. The output has\nthe following properties:\n\\itemize{\n\\item The rows are affect by the join type.\n\\itemize{\n\\item \\code{inner_join()} returns matched \\code{x} rows.\n\\item \\code{left_join()} returns all \\code{x} rows.\n\\item \\code{right_join()}  returns matched of \\code{x} rows, followed by unmatched \\code{y} rows.\n\\item \\code{full_join()}  returns all \\code{x} rows, followed by unmatched \\code{y} rows.\n}\n\\item Output columns include all columns from \\code{x} and all non-key columns from\n\\code{y}. If \\code{keep = TRUE}, the key columns from \\code{y} are included as well.\n\\item If non-key columns in \\code{x} and \\code{y} have the same name, \\code{suffix}es are added\nto disambiguate. If \\code{keep = TRUE} and key columns in \\code{x} and \\code{y} have\nthe same name, \\code{suffix}es are added to disambiguate these as well.\n\\item If \\code{keep = FALSE}, output columns included in \\code{by} are coerced to their\ncommon type between \\code{x} and \\code{y}.\n}\n}\n\\description{\nMutating joins add columns from \\code{y} to \\code{x}, matching observations based on\nthe keys. There are four mutating joins: the inner join, and the three outer\njoins.\n\\subsection{Inner join}{\n\nAn \\code{inner_join()} only keeps observations from \\code{x} that have a matching key\nin \\code{y}.\n\nThe most important property of an inner join is that unmatched rows in either\ninput are not included in the result. This means that generally inner joins\nare not appropriate in most analyses, because it is too easy to lose\nobservations.\n}\n\n\\subsection{Outer joins}{\n\nThe three outer joins keep observations that appear in at least one of the\ndata frames:\n\\itemize{\n\\item A \\code{left_join()} keeps all observations in \\code{x}.\n\\item A \\code{right_join()} keeps all observations in \\code{y}.\n\\item A \\code{full_join()} keeps all observations in \\code{x} and \\code{y}.\n}\n}\n}\n\\section{Many-to-many relationships}{\n\n\n\nBy default, dplyr guards against many-to-many relationships in equality joins\nby throwing a warning. These occur when both of the following are true:\n\\itemize{\n\\item A row in \\code{x} matches multiple rows in \\code{y}.\n\\item A row in \\code{y} matches multiple rows in \\code{x}.\n}\n\nThis is typically surprising, as most joins involve a relationship of\none-to-one, one-to-many, or many-to-one, and is often the result of an\nimproperly specified join. Many-to-many relationships are particularly\nproblematic because they can result in a Cartesian explosion of the number of\nrows returned from the join.\n\nIf a many-to-many relationship is expected, silence this warning by\nexplicitly setting \\code{relationship = \"many-to-many\"}.\n\nIn production code, it is best to preemptively set \\code{relationship} to whatever\nrelationship you expect to exist between the keys of \\code{x} and \\code{y}, as this\nforces an error to occur immediately if the data doesn't align with your\nexpectations.\n\nInequality joins typically result in many-to-many relationships by nature, so\nthey don't warn on them by default, but you should still take extra care when\nspecifying an inequality join, because they also have the capability to\nreturn a large number of rows.\n\nRolling joins don't warn on many-to-many relationships either, but many\nrolling joins follow a many-to-one relationship, so it is often useful to\nset \\code{relationship = \"many-to-one\"} to enforce this.\n\nNote that in SQL, most database providers won't let you specify a\nmany-to-many relationship between two tables, instead requiring that you\ncreate a third \\emph{junction table} that results in two one-to-many relationships\ninstead.\n\n}\n\n\\section{Methods}{\n\n\nThese functions are \\strong{generic}s, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nMethods available in currently loaded packages:\n\\itemize{\n\\item \\code{inner_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"inner_join\")}.\n\\item \\code{left_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"left_join\")}.\n\\item \\code{right_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"right_join\")}.\n\\item \\code{full_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"full_join\")}.\n}\n\n}\n\n\\examples{\ndata(pbmc_small)\ntt <- pbmc_small\ntt |> full_join(tibble::tibble(groups=\"g1\", other=1:4))\n\n}\n\\seealso{\nOther joins: \n\\code{\\link[dplyr]{cross_join}()},\n\\code{\\link[dplyr]{filter-joins}},\n\\code{\\link[dplyr]{nest_join}()}\n}\n"
  },
  {
    "path": "man/get_abundance_sc_long.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/utilities.R\n\\name{get_abundance_sc_long}\n\\alias{get_abundance_sc_long}\n\\title{get abundance long}\n\\usage{\nget_abundance_sc_long(\n  .data,\n  features = NULL,\n  all = FALSE,\n  exclude_zeros = FALSE,\n  assay = Assays(.data),\n  slot = \"data\"\n)\n}\n\\arguments{\n\\item{.data}{A tidyseurat}\n\n\\item{features}{A character}\n\n\\item{all}{A boolean}\n\n\\item{exclude_zeros}{A boolean}\n\n\\item{assay}{assay name to extract feature abundance}\n\n\\item{slot}{slot in the assay, e.g. `data` and `scale.data`}\n}\n\\value{\nA Seurat object\n}\n\\description{\nget abundance long\n}\n\\examples{\ndata(pbmc_small)\npbmc_small \\%>\\%\n  get_abundance_sc_long(features=c(\"HLA-DRA\", \"LYZ\"))\n\n}\n\\keyword{internal}\n"
  },
  {
    "path": "man/get_abundance_sc_wide.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/utilities.R\n\\name{get_abundance_sc_wide}\n\\alias{get_abundance_sc_wide}\n\\title{get abundance wide}\n\\usage{\nget_abundance_sc_wide(\n  .data,\n  features = NULL,\n  all = FALSE,\n  assay = .data@active.assay,\n  slot = \"data\",\n  prefix = \"\"\n)\n}\n\\arguments{\n\\item{.data}{A tidyseurat}\n\n\\item{features}{A character}\n\n\\item{all}{A boolean}\n\n\\item{assay}{assay name to extract feature abundance}\n\n\\item{slot}{slot in the assay, e.g. `data` and `scale.data`}\n\n\\item{prefix}{prefix for the feature names}\n}\n\\value{\nA Seurat object\n}\n\\description{\nget abundance wide\n}\n\\examples{\ndata(pbmc_small)\npbmc_small \\%>\\%\n  get_abundance_sc_wide(features=c(\"HLA-DRA\", \"LYZ\"))\n\n}\n\\keyword{internal}\n"
  },
  {
    "path": "man/ggplot.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/ggplot2_methods.R\n\\name{ggplot}\n\\alias{ggplot}\n\\alias{ggplot.Seurat}\n\\title{Create a new \\code{ggplot} from a \\code{tidyseurat}}\n\\usage{\n\\method{ggplot}{Seurat}(data = NULL, mapping = aes(), ..., environment = parent.frame())\n}\n\\arguments{\n\\item{data}{Default dataset to use for plot. If not already a data.frame,\nwill be converted to one by \\code{\\link[ggplot2:fortify]{fortify()}}. If not specified,\nmust be supplied in each layer added to the plot.}\n\n\\item{mapping}{Default list of aesthetic mappings to use for plot.\nIf not specified, must be supplied in each layer added to the plot.}\n\n\\item{...}{Other arguments passed on to methods. Not currently used.}\n\n\\item{environment}{\\ifelse{html}{\\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\\strong{[Deprecated]}} Used prior to tidy\nevaluation.}\n}\n\\value{\n`ggplot`\n}\n\\description{\n\\code{ggplot()} initializes a ggplot object. It can be used to\ndeclare the input data frame for a graphic and to specify the\nset of aesthetic mappings for the plot, intended to be common throughout all\nsubsequent layers unless specifically overridden.\n}\n\\details{\n\\code{ggplot()} is used to construct the initial plot object,\nand is almost always followed by a plus sign (\\code{+}) to add\ncomponents to the plot.\n\nThere are three common patterns used to invoke \\code{ggplot()}:\n\\itemize{\n\\item \\verb{ggplot(data = df, mapping = aes(x, y, other aesthetics))}\n\\item \\code{ggplot(data = df)}\n\\item \\code{ggplot()}\n}\n\nThe first pattern is recommended if all layers use the same\ndata and the same set of aesthetics, although this method\ncan also be used when adding a layer using data from another\ndata frame.\n\nThe second pattern specifies the default data frame to use\nfor the plot, but no aesthetics are defined up front. This\nis useful when one data frame is used predominantly for the\nplot, but the aesthetics vary from one layer to another.\n\nThe third pattern initializes a skeleton \\code{ggplot} object, which\nis fleshed out as layers are added. This is useful when\nmultiple data frames are used to produce different layers, as\nis often the case in complex graphics.\n\nThe \\verb{data =} and \\verb{mapping =} specifications in the arguments are optional\n(and are often omitted in practice), so long as the data and the mapping\nvalues are passed into the function in the right order. In the examples\nbelow, however, they are left in place for clarity.\n}\n\\examples{\nlibrary(ggplot2)\ndata(pbmc_small)\npbmc_small |> \n  ggplot(aes(groups, nCount_RNA)) +\n  geom_boxplot()\n\n}\n\\seealso{\nThe \\href{https://ggplot2-book.org/getting-started}{first steps chapter} of the online ggplot2 book.\n}\n"
  },
  {
    "path": "man/glimpse.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/tibble_methods.R\n\\name{glimpse}\n\\alias{glimpse}\n\\alias{glimpse.tidyseurat}\n\\title{Get a glimpse of your data}\n\\usage{\n\\method{glimpse}{tidyseurat}(x, width = NULL, ...)\n}\n\\arguments{\n\\item{x}{An object to glimpse at.}\n\n\\item{width}{Width of output: defaults to the setting of the\n\\code{width} \\link[pillar:pillar_options]{option} (if finite)\nor the width of the console.}\n\n\\item{...}{Unused, for extensibility.}\n}\n\\value{\nx original x is (invisibly) returned, allowing \\code{glimpse()} to be\nused within a data pipe line.\n}\n\\description{\n\\code{glimpse()} is like a transposed version of \\code{print()}:\ncolumns run down the page, and data runs across.\nThis makes it possible to see every column in a data frame.\nIt's a little like \\code{\\link[=str]{str()}} applied to a data frame\nbut it tries to show you as much data as possible.\n(And it always shows the underlying data, even when applied\nto a remote data source.)\n\nSee \\code{\\link[pillar:format_glimpse]{format_glimpse()}} for details on the formatting.\n}\n\\section{S3 methods}{\n\n\n\\code{glimpse} is an S3 generic with a customised method for \\code{tbl}s and\n\\code{data.frames}, and a default method that calls \\code{\\link[=str]{str()}}.\n\n}\n\n\\examples{\ndata(pbmc_small)\npbmc_small |> glimpse()\n\n}\n"
  },
  {
    "path": "man/group_by.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{group_by}\n\\alias{group_by}\n\\alias{group_by.Seurat}\n\\title{Group by one or more variables}\n\\usage{\n\\method{group_by}{Seurat}(.data, ..., .add = FALSE, .drop = group_by_drop_default(.data))\n}\n\\arguments{\n\\item{.data}{A data frame, data frame extension (e.g. a tibble), or a\nlazy data frame (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{...}{<\\code{\\link[rlang:args_data_masking]{data-masking}}> In \\code{group_by()},\nvariables or computations to group by. Computations are always done on the\nungrouped data frame. To perform computations on the grouped data, you need\nto use a separate \\code{mutate()} step before the \\code{group_by()}.\nComputations are not allowed in \\code{nest_by()}.\nIn \\code{ungroup()}, variables to remove from the grouping.}\n\n\\item{.add}{When \\code{FALSE}, the default, \\code{group_by()} will\noverride existing groups. To add to the existing groups, use\n\\code{.add = TRUE}.}\n\n\\item{.drop}{Drop groups formed by factor levels that don't appear in the\ndata? The default is \\code{TRUE} except when \\code{.data} has been previously\ngrouped with \\code{.drop = FALSE}. See \\code{\\link[dplyr:group_by_drop_default]{group_by_drop_default()}} for details.}\n}\n\\value{\nA grouped data frame with class \\code{\\link[dplyr]{grouped_df}},\nunless the combination of \\code{...} and \\code{add} yields a empty set of\ngrouping columns, in which case a tibble will be returned.\n}\n\\description{\nMost data operations are done on groups defined by variables.\n\\code{group_by()} takes an existing tbl and converts it into a grouped tbl\nwhere operations are performed \"by group\". \\code{ungroup()} removes grouping.\n}\n\\section{Methods}{\n\n\nThese function are \\strong{generic}s, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nMethods available in currently loaded packages:\n\\itemize{\n\\item \\code{group_by()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"group_by\")}.\n\\item \\code{ungroup()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"ungroup\")}.\n}\n\n}\n\n\\section{Ordering}{\n\n\nCurrently, \\code{group_by()} internally orders the groups in ascending order. This\nresults in ordered output from functions that aggregate groups, such as\n\\code{\\link[dplyr:summarise]{summarise()}}.\n\nWhen used as grouping columns, character vectors are ordered in the C locale\nfor performance and reproducibility across R sessions. If the resulting\nordering of your grouped operation matters and is dependent on the locale,\nyou should follow up the grouped operation with an explicit call to\n\\code{\\link[dplyr:arrange]{arrange()}} and set the \\code{.locale} argument. For example:\n\n\\if{html}{\\out{<div class=\"sourceCode\">}}\\preformatted{data |>\n  group_by(chr) |>\n  summarise(avg = mean(x)) |>\n  arrange(chr, .locale = \"en\")\n}\\if{html}{\\out{</div>}}\n\nThis is often useful as a preliminary step before generating content intended\nfor humans, such as an HTML table.\n\\subsection{Legacy behavior}{\n\n\\ifelse{html}{\\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\\strong{[Deprecated]}}\n\nPrior to dplyr 1.1.0, character vector grouping columns were ordered in the\nsystem locale. Setting the global option \\code{dplyr.legacy_locale} to \\code{TRUE}\nretains this legacy behavior, but this has been deprecated. Update existing\ncode to explicitly call \\code{arrange(.locale = )} instead. Run\n\\code{Sys.getlocale(\"LC_COLLATE\")} to determine your system locale, and compare\nthat against the list in \\code{\\link[stringi:stri_locale_list]{stringi::stri_locale_list()}} to find an appropriate\nvalue for \\code{.locale}, i.e. for American English, \\code{\"en_US\"}.\n}\n\n}\n\n\\examples{\ndata(\"pbmc_small\")\npbmc_small |>  group_by(groups)\n\n}\n\\seealso{\nOther grouping functions: \n\\code{\\link[dplyr]{group_map}()},\n\\code{\\link[dplyr]{group_nest}()},\n\\code{\\link[dplyr]{group_split}()},\n\\code{\\link[dplyr]{group_trim}()}\n}\n"
  },
  {
    "path": "man/group_split.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{group_split}\n\\alias{group_split}\n\\alias{group_split.Seurat}\n\\title{Split data frame by groups}\n\\usage{\n\\method{group_split}{Seurat}(.tbl, ..., .keep = TRUE)\n}\n\\arguments{\n\\item{.tbl}{A tbl.}\n\n\\item{...}{If \\code{.tbl} is an ungrouped data frame, a grouping specification,\nforwarded to \\code{\\link[dplyr:group_by]{group_by()}}.}\n\n\\item{.keep}{Should the grouping columns be kept?}\n}\n\\value{\nA list of tibbles. Each tibble contains the rows of \\code{.tbl} for the\nassociated group and all the columns, including the grouping variables.\nNote that this returns a \\link[vctrs:list_of]{list_of} which is slightly\nstricter than a simple list but is useful for representing lists where\nevery element has the same type.\n}\n\\description{\n\\ifelse{html}{\\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\\strong{[Experimental]}}\n\n\\code{\\link[dplyr:group_split]{group_split()}} works like \\code{\\link[base:split]{base::split()}} but:\n\\itemize{\n\\item It uses the grouping structure from \\code{\\link[dplyr:group_by]{group_by()}} and therefore is subject\nto the data mask\n\\item It does not name the elements of the list based on the grouping as this\nonly works well for a single character grouping variable. Instead,\nuse \\code{\\link[dplyr:group_keys]{group_keys()}} to access a data frame that defines the groups.\n}\n\n\\code{group_split()} is primarily designed to work with grouped data frames.\nYou can pass \\code{...} to group and split an ungrouped data frame, but this\nis generally not very useful as you want have easy access to the group\nmetadata.\n}\n\\section{Lifecycle}{\n\n\n\\code{group_split()} is not stable because you can achieve very similar results by\nmanipulating the nested column returned from\n\\code{\\link[tidyr:nest]{tidyr::nest(.by =)}}. That also retains the group keys all\nwithin a single data structure. \\code{group_split()} may be deprecated in the\nfuture.\n\n}\n\n\\examples{\ndata(pbmc_small)\npbmc_small |> group_split(groups)\n\n}\n\\seealso{\nOther grouping functions: \n\\code{\\link[dplyr]{group_by}()},\n\\code{\\link[dplyr]{group_map}()},\n\\code{\\link[dplyr]{group_nest}()},\n\\code{\\link[dplyr]{group_trim}()}\n}\n"
  },
  {
    "path": "man/inner_join.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{inner_join}\n\\alias{inner_join}\n\\alias{inner_join.Seurat}\n\\title{Mutating joins}\n\\usage{\n\\method{inner_join}{Seurat}(x, y, by = NULL, copy = FALSE, suffix = c(\".x\", \".y\"), ...)\n}\n\\arguments{\n\\item{x, y}{A pair of data frames, data frame extensions (e.g. a tibble), or\nlazy data frames (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{by}{A join specification created with \\code{\\link[dplyr:join_by]{join_by()}}, or a character\nvector of variables to join by.\n\nIf \\code{NULL}, the default, \\verb{*_join()} will perform a natural join, using all\nvariables in common across \\code{x} and \\code{y}. A message lists the variables so\nthat you can check they're correct; suppress the message by supplying \\code{by}\nexplicitly.\n\nTo join on different variables between \\code{x} and \\code{y}, use a \\code{\\link[dplyr:join_by]{join_by()}}\nspecification. For example, \\code{join_by(a == b)} will match \\code{x$a} to \\code{y$b}.\n\nTo join by multiple variables, use a \\code{\\link[dplyr:join_by]{join_by()}} specification with\nmultiple expressions. For example, \\code{join_by(a == b, c == d)} will match\n\\code{x$a} to \\code{y$b} and \\code{x$c} to \\code{y$d}. If the column names are the same between\n\\code{x} and \\code{y}, you can shorten this by listing only the variable names, like\n\\code{join_by(a, c)}.\n\n\\code{\\link[dplyr:join_by]{join_by()}} can also be used to perform inequality, rolling, and overlap\njoins. See the documentation at \\link[dplyr:join_by]{?join_by} for details on\nthese types of joins.\n\nFor simple equality joins, you can alternatively specify a character vector\nof variable names to join by. For example, \\code{by = c(\"a\", \"b\")} joins \\code{x$a}\nto \\code{y$a} and \\code{x$b} to \\code{y$b}. If variable names differ between \\code{x} and \\code{y},\nuse a named character vector like \\code{by = c(\"x_a\" = \"y_a\", \"x_b\" = \"y_b\")}.\n\nTo perform a cross-join, generating all combinations of \\code{x} and \\code{y}, see\n\\code{\\link[dplyr:cross_join]{cross_join()}}.}\n\n\\item{copy}{If \\code{x} and \\code{y} are not from the same data source,\nand \\code{copy} is \\code{TRUE}, then \\code{y} will be copied into the\nsame src as \\code{x}.  This allows you to join tables across srcs, but\nit is a potentially expensive operation so you must opt into it.}\n\n\\item{suffix}{If there are non-joined duplicate variables in \\code{x} and\n\\code{y}, these suffixes will be added to the output to disambiguate them.\nShould be a character vector of length 2.}\n\n\\item{...}{Other parameters passed onto methods.}\n}\n\\value{\nAn object of the same type as \\code{x} (including the same groups). The order of\nthe rows and columns of \\code{x} is preserved as much as possible. The output has\nthe following properties:\n\\itemize{\n\\item The rows are affect by the join type.\n\\itemize{\n\\item \\code{inner_join()} returns matched \\code{x} rows.\n\\item \\code{left_join()} returns all \\code{x} rows.\n\\item \\code{right_join()}  returns matched of \\code{x} rows, followed by unmatched \\code{y} rows.\n\\item \\code{full_join()}  returns all \\code{x} rows, followed by unmatched \\code{y} rows.\n}\n\\item Output columns include all columns from \\code{x} and all non-key columns from\n\\code{y}. If \\code{keep = TRUE}, the key columns from \\code{y} are included as well.\n\\item If non-key columns in \\code{x} and \\code{y} have the same name, \\code{suffix}es are added\nto disambiguate. If \\code{keep = TRUE} and key columns in \\code{x} and \\code{y} have\nthe same name, \\code{suffix}es are added to disambiguate these as well.\n\\item If \\code{keep = FALSE}, output columns included in \\code{by} are coerced to their\ncommon type between \\code{x} and \\code{y}.\n}\n}\n\\description{\nMutating joins add columns from \\code{y} to \\code{x}, matching observations based on\nthe keys. There are four mutating joins: the inner join, and the three outer\njoins.\n\\subsection{Inner join}{\n\nAn \\code{inner_join()} only keeps observations from \\code{x} that have a matching key\nin \\code{y}.\n\nThe most important property of an inner join is that unmatched rows in either\ninput are not included in the result. This means that generally inner joins\nare not appropriate in most analyses, because it is too easy to lose\nobservations.\n}\n\n\\subsection{Outer joins}{\n\nThe three outer joins keep observations that appear in at least one of the\ndata frames:\n\\itemize{\n\\item A \\code{left_join()} keeps all observations in \\code{x}.\n\\item A \\code{right_join()} keeps all observations in \\code{y}.\n\\item A \\code{full_join()} keeps all observations in \\code{x} and \\code{y}.\n}\n}\n}\n\\section{Many-to-many relationships}{\n\n\n\nBy default, dplyr guards against many-to-many relationships in equality joins\nby throwing a warning. These occur when both of the following are true:\n\\itemize{\n\\item A row in \\code{x} matches multiple rows in \\code{y}.\n\\item A row in \\code{y} matches multiple rows in \\code{x}.\n}\n\nThis is typically surprising, as most joins involve a relationship of\none-to-one, one-to-many, or many-to-one, and is often the result of an\nimproperly specified join. Many-to-many relationships are particularly\nproblematic because they can result in a Cartesian explosion of the number of\nrows returned from the join.\n\nIf a many-to-many relationship is expected, silence this warning by\nexplicitly setting \\code{relationship = \"many-to-many\"}.\n\nIn production code, it is best to preemptively set \\code{relationship} to whatever\nrelationship you expect to exist between the keys of \\code{x} and \\code{y}, as this\nforces an error to occur immediately if the data doesn't align with your\nexpectations.\n\nInequality joins typically result in many-to-many relationships by nature, so\nthey don't warn on them by default, but you should still take extra care when\nspecifying an inequality join, because they also have the capability to\nreturn a large number of rows.\n\nRolling joins don't warn on many-to-many relationships either, but many\nrolling joins follow a many-to-one relationship, so it is often useful to\nset \\code{relationship = \"many-to-one\"} to enforce this.\n\nNote that in SQL, most database providers won't let you specify a\nmany-to-many relationship between two tables, instead requiring that you\ncreate a third \\emph{junction table} that results in two one-to-many relationships\ninstead.\n\n}\n\n\\section{Methods}{\n\n\nThese functions are \\strong{generic}s, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nMethods available in currently loaded packages:\n\\itemize{\n\\item \\code{inner_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"inner_join\")}.\n\\item \\code{left_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"left_join\")}.\n\\item \\code{right_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"right_join\")}.\n\\item \\code{full_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"full_join\")}.\n}\n\n}\n\n\\examples{\ndata(pbmc_small)\ntt <- pbmc_small\ntt |> inner_join(tt |> \n  distinct(groups) |>  \n  mutate(new_column=1:2) |> \n  slice(1))\n\n}\n\\seealso{\nOther joins: \n\\code{\\link[dplyr]{cross_join}()},\n\\code{\\link[dplyr]{filter-joins}},\n\\code{\\link[dplyr]{nest_join}()}\n}\n"
  },
  {
    "path": "man/join_features.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/methods.R\n\\name{join_features}\n\\alias{join_features}\n\\alias{join_features,Seurat-method}\n\\title{join_features}\n\\usage{\n\\S4method{join_features}{Seurat}(\n  .data,\n  features = NULL,\n  all = FALSE,\n  exclude_zeros = FALSE,\n  shape = \"wide\",\n  assay = NULL,\n  slot = \"data\",\n  ...\n)\n}\n\\arguments{\n\\item{.data}{A tidyseurat object}\n\n\\item{features}{A vector of feature identifiers to join}\n\n\\item{all}{If TRUE return all}\n\n\\item{exclude_zeros}{If TRUE exclude zero values}\n\n\\item{shape}{Format of the returned table \"long\" or \"wide\"}\n\n\\item{assay}{assay name to extract feature abundance}\n\n\\item{slot}{slot name to extract feature abundance}\n\n\\item{...}{Parameters to pass to join wide, i.e. assay name to extract feature abundance from and gene prefix, for shape=\"wide\"}\n}\n\\value{\nA `tidyseurat` object\n  containing information for the specified features.\n}\n\\description{\njoin_features() extracts and joins information for specific\n  features\n}\n\\details{\nThis function extracts information for specified features and\n  returns the information in either long or wide format.\n}\n\\examples{\ndata(pbmc_small)\npbmc_small \\%>\\% join_features(\n  features=c(\"HLA-DRA\", \"LYZ\"))\n\n}\n"
  },
  {
    "path": "man/join_transcripts.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/methods_DEPRECATED.R\n\\name{join_transcripts}\n\\alias{join_transcripts}\n\\title{(DEPRECATED) Extract and join information for transcripts.}\n\\usage{\njoin_transcripts(\n  .data,\n  transcripts = NULL,\n  all = FALSE,\n  exclude_zeros = FALSE,\n  shape = \"wide\",\n  ...\n)\n}\n\\arguments{\n\\item{.data}{A tidyseurat object}\n\n\\item{transcripts}{A vector of transcript identifiers to join}\n\n\\item{all}{If TRUE return all}\n\n\\item{exclude_zeros}{If TRUE exclude zero values}\n\n\\item{shape}{Format of the returned table \"long\" or \"wide\"}\n\n\\item{...}{Parameters to pass to join wide, i.e. assay name to extract transcript abundance from}\n}\n\\value{\nA `tbl` containing the information.for the specified transcripts\n}\n\\description{\njoin_transcripts() extracts and joins information for specified transcripts\n}\n\\details{\nDEPRECATED, please use join_features()\n}\n\\examples{\n\nprint(\"DEPRECATED\")\n\n\n}\n"
  },
  {
    "path": "man/left_join.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{left_join}\n\\alias{left_join}\n\\alias{left_join.Seurat}\n\\title{Mutating joins}\n\\usage{\n\\method{left_join}{Seurat}(x, y, by = NULL, copy = FALSE, suffix = c(\".x\", \".y\"), ...)\n}\n\\arguments{\n\\item{x, y}{A pair of data frames, data frame extensions (e.g. a tibble), or\nlazy data frames (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{by}{A join specification created with \\code{\\link[dplyr:join_by]{join_by()}}, or a character\nvector of variables to join by.\n\nIf \\code{NULL}, the default, \\verb{*_join()} will perform a natural join, using all\nvariables in common across \\code{x} and \\code{y}. A message lists the variables so\nthat you can check they're correct; suppress the message by supplying \\code{by}\nexplicitly.\n\nTo join on different variables between \\code{x} and \\code{y}, use a \\code{\\link[dplyr:join_by]{join_by()}}\nspecification. For example, \\code{join_by(a == b)} will match \\code{x$a} to \\code{y$b}.\n\nTo join by multiple variables, use a \\code{\\link[dplyr:join_by]{join_by()}} specification with\nmultiple expressions. For example, \\code{join_by(a == b, c == d)} will match\n\\code{x$a} to \\code{y$b} and \\code{x$c} to \\code{y$d}. If the column names are the same between\n\\code{x} and \\code{y}, you can shorten this by listing only the variable names, like\n\\code{join_by(a, c)}.\n\n\\code{\\link[dplyr:join_by]{join_by()}} can also be used to perform inequality, rolling, and overlap\njoins. See the documentation at \\link[dplyr:join_by]{?join_by} for details on\nthese types of joins.\n\nFor simple equality joins, you can alternatively specify a character vector\nof variable names to join by. For example, \\code{by = c(\"a\", \"b\")} joins \\code{x$a}\nto \\code{y$a} and \\code{x$b} to \\code{y$b}. If variable names differ between \\code{x} and \\code{y},\nuse a named character vector like \\code{by = c(\"x_a\" = \"y_a\", \"x_b\" = \"y_b\")}.\n\nTo perform a cross-join, generating all combinations of \\code{x} and \\code{y}, see\n\\code{\\link[dplyr:cross_join]{cross_join()}}.}\n\n\\item{copy}{If \\code{x} and \\code{y} are not from the same data source,\nand \\code{copy} is \\code{TRUE}, then \\code{y} will be copied into the\nsame src as \\code{x}.  This allows you to join tables across srcs, but\nit is a potentially expensive operation so you must opt into it.}\n\n\\item{suffix}{If there are non-joined duplicate variables in \\code{x} and\n\\code{y}, these suffixes will be added to the output to disambiguate them.\nShould be a character vector of length 2.}\n\n\\item{...}{Other parameters passed onto methods.}\n}\n\\value{\nAn object of the same type as \\code{x} (including the same groups). The order of\nthe rows and columns of \\code{x} is preserved as much as possible. The output has\nthe following properties:\n\\itemize{\n\\item The rows are affect by the join type.\n\\itemize{\n\\item \\code{inner_join()} returns matched \\code{x} rows.\n\\item \\code{left_join()} returns all \\code{x} rows.\n\\item \\code{right_join()}  returns matched of \\code{x} rows, followed by unmatched \\code{y} rows.\n\\item \\code{full_join()}  returns all \\code{x} rows, followed by unmatched \\code{y} rows.\n}\n\\item Output columns include all columns from \\code{x} and all non-key columns from\n\\code{y}. If \\code{keep = TRUE}, the key columns from \\code{y} are included as well.\n\\item If non-key columns in \\code{x} and \\code{y} have the same name, \\code{suffix}es are added\nto disambiguate. If \\code{keep = TRUE} and key columns in \\code{x} and \\code{y} have\nthe same name, \\code{suffix}es are added to disambiguate these as well.\n\\item If \\code{keep = FALSE}, output columns included in \\code{by} are coerced to their\ncommon type between \\code{x} and \\code{y}.\n}\n}\n\\description{\nMutating joins add columns from \\code{y} to \\code{x}, matching observations based on\nthe keys. There are four mutating joins: the inner join, and the three outer\njoins.\n\\subsection{Inner join}{\n\nAn \\code{inner_join()} only keeps observations from \\code{x} that have a matching key\nin \\code{y}.\n\nThe most important property of an inner join is that unmatched rows in either\ninput are not included in the result. This means that generally inner joins\nare not appropriate in most analyses, because it is too easy to lose\nobservations.\n}\n\n\\subsection{Outer joins}{\n\nThe three outer joins keep observations that appear in at least one of the\ndata frames:\n\\itemize{\n\\item A \\code{left_join()} keeps all observations in \\code{x}.\n\\item A \\code{right_join()} keeps all observations in \\code{y}.\n\\item A \\code{full_join()} keeps all observations in \\code{x} and \\code{y}.\n}\n}\n}\n\\section{Many-to-many relationships}{\n\n\n\nBy default, dplyr guards against many-to-many relationships in equality joins\nby throwing a warning. These occur when both of the following are true:\n\\itemize{\n\\item A row in \\code{x} matches multiple rows in \\code{y}.\n\\item A row in \\code{y} matches multiple rows in \\code{x}.\n}\n\nThis is typically surprising, as most joins involve a relationship of\none-to-one, one-to-many, or many-to-one, and is often the result of an\nimproperly specified join. Many-to-many relationships are particularly\nproblematic because they can result in a Cartesian explosion of the number of\nrows returned from the join.\n\nIf a many-to-many relationship is expected, silence this warning by\nexplicitly setting \\code{relationship = \"many-to-many\"}.\n\nIn production code, it is best to preemptively set \\code{relationship} to whatever\nrelationship you expect to exist between the keys of \\code{x} and \\code{y}, as this\nforces an error to occur immediately if the data doesn't align with your\nexpectations.\n\nInequality joins typically result in many-to-many relationships by nature, so\nthey don't warn on them by default, but you should still take extra care when\nspecifying an inequality join, because they also have the capability to\nreturn a large number of rows.\n\nRolling joins don't warn on many-to-many relationships either, but many\nrolling joins follow a many-to-one relationship, so it is often useful to\nset \\code{relationship = \"many-to-one\"} to enforce this.\n\nNote that in SQL, most database providers won't let you specify a\nmany-to-many relationship between two tables, instead requiring that you\ncreate a third \\emph{junction table} that results in two one-to-many relationships\ninstead.\n\n}\n\n\\section{Methods}{\n\n\nThese functions are \\strong{generic}s, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nMethods available in currently loaded packages:\n\\itemize{\n\\item \\code{inner_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"inner_join\")}.\n\\item \\code{left_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"left_join\")}.\n\\item \\code{right_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"right_join\")}.\n\\item \\code{full_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"full_join\")}.\n}\n\n}\n\n\\examples{\ndata(pbmc_small)\ntt <- pbmc_small\ntt |> left_join(tt |>  \n  distinct(groups) |> \n  mutate(new_column=1:2))\n\n}\n\\seealso{\nOther joins: \n\\code{\\link[dplyr]{cross_join}()},\n\\code{\\link[dplyr]{filter-joins}},\n\\code{\\link[dplyr]{nest_join}()}\n}\n"
  },
  {
    "path": "man/mutate.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{mutate}\n\\alias{mutate}\n\\alias{mutate.Seurat}\n\\title{Create, modify, and delete columns}\n\\usage{\n\\method{mutate}{Seurat}(.data, ...)\n}\n\\arguments{\n\\item{.data}{A data frame, data frame extension (e.g. a tibble), or a\nlazy data frame (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{...}{<\\code{\\link[rlang:args_data_masking]{data-masking}}> Name-value pairs.\nThe name gives the name of the column in the output.\n\nThe value can be:\n\\itemize{\n\\item A vector of length 1, which will be recycled to the correct length.\n\\item A vector the same length as the current group (or the whole data frame\nif ungrouped).\n\\item \\code{NULL}, to remove the column.\n\\item A data frame or tibble, to create multiple columns in the output.\n}}\n}\n\\value{\nAn object of the same type as \\code{.data}. The output has the following\nproperties:\n\\itemize{\n\\item Columns from \\code{.data} will be preserved according to the \\code{.keep} argument.\n\\item Existing columns that are modified by \\code{...} will always be returned in\ntheir original location.\n\\item New columns created through \\code{...} will be placed according to the\n\\code{.before} and \\code{.after} arguments.\n\\item The number of rows is not affected.\n\\item Columns given the value \\code{NULL} will be removed.\n\\item Groups will be recomputed if a grouping variable is mutated.\n\\item Data frame attributes are preserved.\n}\n}\n\\description{\n\\code{mutate()} creates new columns that are functions of existing variables.\nIt can also modify (if the name is the same as an existing\ncolumn) and delete columns (by setting their value to \\code{NULL}).\n}\n\\section{Useful mutate functions}{\n\n\n\\itemize{\n\\item \\code{\\link{+}}, \\code{\\link{-}}, \\code{\\link[=log]{log()}}, etc., for their usual mathematical meanings\n\\item \\code{\\link[dplyr:lead]{lead()}}, \\code{\\link[dplyr:lag]{lag()}}\n\\item \\code{\\link[dplyr:dense_rank]{dense_rank()}}, \\code{\\link[dplyr:min_rank]{min_rank()}}, \\code{\\link[dplyr:percent_rank]{percent_rank()}}, \\code{\\link[dplyr:row_number]{row_number()}},\n\\code{\\link[dplyr:cume_dist]{cume_dist()}}, \\code{\\link[dplyr:ntile]{ntile()}}\n\\item \\code{\\link[=cumsum]{cumsum()}}, \\code{\\link[dplyr:cummean]{cummean()}}, \\code{\\link[=cummin]{cummin()}}, \\code{\\link[=cummax]{cummax()}}, \\code{\\link[dplyr:cumany]{cumany()}}, \\code{\\link[dplyr:cumall]{cumall()}}\n\\item \\code{\\link[dplyr:na_if]{na_if()}}, \\code{\\link[dplyr:coalesce]{coalesce()}}\n\\item \\code{\\link[dplyr:if_else]{if_else()}}, \\code{\\link[dplyr:recode]{recode()}}, \\code{\\link[dplyr:case_when]{case_when()}}\n}\n\n}\n\n\\section{Grouped tibbles}{\n\n\n\nBecause mutating expressions are computed within groups, they may\nyield different results on grouped tibbles. This will be the case\nas soon as an aggregating, lagging, or ranking function is\ninvolved. Compare this ungrouped mutate:\n\n\\if{html}{\\out{<div class=\"sourceCode\">}}\\preformatted{starwars |>\n  select(name, mass, species) |>\n  mutate(mass_norm = mass / mean(mass, na.rm = TRUE))\n}\\if{html}{\\out{</div>}}\n\nWith the grouped equivalent:\n\n\\if{html}{\\out{<div class=\"sourceCode\">}}\\preformatted{starwars |>\n  select(name, mass, species) |>\n  group_by(species) |>\n  mutate(mass_norm = mass / mean(mass, na.rm = TRUE))\n}\\if{html}{\\out{</div>}}\n\nThe former normalises \\code{mass} by the global average whereas the\nlatter normalises by the averages within species levels.\n\n}\n\n\\section{Methods}{\n\n\nThis function is a \\strong{generic}, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nMethods available in currently loaded packages:\n\\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"mutate\")}.\n\n}\n\n\\examples{\ndata(pbmc_small)\npbmc_small |> mutate(nFeature_RNA=1)\n\n}\n\\seealso{\nOther single table verbs: \n\\code{\\link{arrange}()},\n\\code{\\link{rename}()},\n\\code{\\link{slice}()},\n\\code{\\link{summarise}()}\n}\n\\concept{single table verbs}\n"
  },
  {
    "path": "man/nest.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/tidyr_methods.R\n\\name{nest}\n\\alias{nest}\n\\alias{nest.Seurat}\n\\title{Nest rows into a list-column of data frames}\n\\usage{\n\\method{nest}{Seurat}(.data, ..., .names_sep = NULL)\n}\n\\arguments{\n\\item{.data}{A data frame.}\n\n\\item{...}{<\\code{\\link[tidyr:tidyr_tidy_select]{tidy-select}}> Columns to nest; these will\nappear in the inner data frames.\n\nSpecified using name-variable pairs of the form\n\\code{new_col = c(col1, col2, col3)}. The right hand side can be any valid\ntidyselect expression.\n\nIf not supplied, then \\code{...} is derived as all columns \\emph{not} selected by\n\\code{.by}, and will use the column name from \\code{.key}.\n\n\\ifelse{html}{\\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\\strong{[Deprecated]}}:\npreviously you could write \\code{df |> nest(x, y, z)}.\nConvert to \\code{df |> nest(data = c(x, y, z))}.}\n\n\\item{.names_sep}{If \\code{NULL}, the default, the inner names will come from\nthe former outer names. If a string, the  new inner names will use the\nouter names with \\code{names_sep} automatically stripped. This makes\n\\code{names_sep} roughly symmetric between nesting and unnesting.}\n}\n\\value{\n`tidyseurat_nested`\n}\n\\description{\nNesting creates a list-column of data frames; unnesting flattens it back out\ninto regular columns. Nesting is implicitly a summarising operation: you\nget one row for each group defined by the non-nested columns. This is useful\nin conjunction with other summaries that work with whole datasets, most\nnotably models.\n\nLearn more in \\code{vignette(\"nest\")}.\n}\n\\details{\nIf neither \\code{...} nor \\code{.by} are supplied, \\code{nest()} will nest all variables,\nand will use the column name supplied through \\code{.key}.\n}\n\\section{New syntax}{\n\n\ntidyr 1.0.0 introduced a new syntax for \\code{nest()} and \\code{unnest()} that's\ndesigned to be more similar to other functions. Converting to the new syntax\nshould be straightforward (guided by the message you'll receive) but if\nyou just need to run an old analysis, you can easily revert to the previous\nbehaviour using \\code{\\link[tidyr:nest_legacy]{nest_legacy()}} and \\code{\\link[tidyr:unnest_legacy]{unnest_legacy()}} as follows:\n\n\\if{html}{\\out{<div class=\"sourceCode\">}}\\preformatted{library(tidyr)\nnest <- nest_legacy\nunnest <- unnest_legacy\n}\\if{html}{\\out{</div>}}\n\n}\n\n\\section{Grouped data frames}{\n\n\n\\code{df |> nest(data = c(x, y))} specifies the columns to be nested; i.e. the\ncolumns that will appear in the inner data frame. \\code{df |> nest(.by = c(x, y))} specifies the columns to nest \\emph{by}; i.e. the columns that will remain in\nthe outer data frame. An alternative way to achieve the latter is to \\code{nest()}\na grouped data frame created by \\code{\\link[dplyr:group_by]{dplyr::group_by()}}. The grouping variables\nremain in the outer data frame and the others are nested. The result\npreserves the grouping of the input.\n\nVariables supplied to \\code{nest()} will override grouping variables so that\n\\code{df |> group_by(x, y) |> nest(data = !z)} will be equivalent to\n\\code{df |> nest(data = !z)}.\n\nYou can't supply \\code{.by} with a grouped data frame, as the groups already\nrepresent what you are nesting by.\n\n}\n\n\\examples{\ndata(pbmc_small)\npbmc_small |> \n    nest(data=-groups) |> \n    unnest(data)\n\n}\n"
  },
  {
    "path": "man/pbmc_small_nested_interactions.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/data.R\n\\docType{data}\n\\name{pbmc_small_nested_interactions}\n\\alias{pbmc_small_nested_interactions}\n\\title{Intercellular ligand-receptor interactions for \n38 ligands from a single cell RNA-seq cluster.}\n\\format{\nA `tibble` containing 100 rows and 9 columns.\n  Cells are a subsample of the PBMC dataset of 2,700 single cells. \n  Cell interactions were identified with `SingleCellSignalR`.\n\\describe{\n  \\item{sample}{sample identifier}\n  \\item{ligand}{cluster and ligand identifier}\n  \\item{receptor}{cluster and receptor identifier}\n  \\item{ligand.name}{ligand name}\n  \\item{receptor.name}{receptor name}\n  \\item{origin}{cluster containing ligand}\n  \\item{destination}{cluster containing receptor}\n  \\item{interaction.type}{type of interation, paracrine or autocrine}\n  \\item{LRscore}{interaction score}\n}\n}\n\\source{\n\\url{https://satijalab.org/seurat/v3.1/pbmc3k_tutorial.html}\n}\n\\usage{\ndata(pbmc_small_nested_interactions)\n}\n\\value{\n`tibble`\n}\n\\description{\nA dataset containing ligand-receptor interactions within a sample.\nThere are 38 ligands from a single cell cluster versus 35 receptors \nin 6 other clusters.\n}\n\\keyword{datasets}\n"
  },
  {
    "path": "man/pipe.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/utils-pipe.R\n\\name{\\%>\\%}\n\\alias{\\%>\\%}\n\\title{Pipe operator}\n\\usage{\nlhs \\%>\\% rhs\n}\n\\value{\nvoid\n}\n\\description{\nSee \\code{magrittr::\\link[magrittr:pipe]{\\%>\\%}} for details.\n}\n\\examples{\ndata(pbmc_small)\npbmc_small \\%>\\% print()\n}\n\\keyword{internal}\n"
  },
  {
    "path": "man/pivot_longer.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/tidyr_methods.R\n\\name{pivot_longer}\n\\alias{pivot_longer}\n\\alias{pivot_longer.Seurat}\n\\title{Pivot data from wide to long}\n\\usage{\n\\method{pivot_longer}{Seurat}(\n  data,\n  cols,\n  names_to = \"name\",\n  names_prefix = NULL,\n  names_sep = NULL,\n  names_pattern = NULL,\n  names_ptypes = NULL,\n  names_transform = NULL,\n  names_repair = \"check_unique\",\n  values_to = \"value\",\n  values_drop_na = FALSE,\n  values_ptypes = NULL,\n  values_transform = NULL,\n  ...\n)\n}\n\\arguments{\n\\item{data}{A data frame to pivot.}\n\n\\item{cols}{<\\code{\\link[tidyr:tidyr_tidy_select]{tidy-select}}> Columns to pivot into\nlonger format.}\n\n\\item{names_to}{A character vector specifying the new column or columns to\ncreate from the information stored in the column names of \\code{data} specified\nby \\code{cols}.\n\\itemize{\n\\item If length 0, or if \\code{NULL} is supplied, no columns will be created.\n\\item If length 1, a single column will be created which will contain the\ncolumn names specified by \\code{cols}.\n\\item If length >1, multiple columns will be created. In this case, one of\n\\code{names_sep} or \\code{names_pattern} must be supplied to specify how the\ncolumn names should be split. There are also two additional character\nvalues you can take advantage of:\n\\itemize{\n\\item \\code{NA} will discard the corresponding component of the column name.\n\\item \\code{\".value\"} indicates that the corresponding component of the column\nname defines the name of the output column containing the cell values,\noverriding \\code{values_to} entirely.\n}\n}}\n\n\\item{names_prefix}{A regular expression used to remove matching text\nfrom the start of each variable name.}\n\n\\item{names_sep, names_pattern}{If \\code{names_to} contains multiple values,\nthese arguments control how the column name is broken up.\n\n\\code{names_sep} takes the same specification as \\code{\\link[tidyr:separate]{separate()}}, and can either\nbe a numeric vector (specifying positions to break on), or a single string\n(specifying a regular expression to split on).\n\n\\code{names_pattern} takes the same specification as \\code{\\link[tidyr:extract]{extract()}}, a regular\nexpression containing matching groups (\\verb{()}).\n\nIf these arguments do not give you enough control, use\n\\code{pivot_longer_spec()} to create a spec object and process manually as\nneeded.}\n\n\\item{names_ptypes, values_ptypes}{Optionally, a list of column name-prototype\npairs. Alternatively, a single empty prototype can be supplied, which will\nbe applied to all columns. A prototype (or ptype for short) is a\nzero-length vector (like \\code{integer()} or \\code{numeric()}) that defines the type,\nclass, and attributes of a vector. Use these arguments if you want to\nconfirm that the created columns are the types that you expect. Note that\nif you want to change (instead of confirm) the types of specific columns,\nyou should use \\code{names_transform} or \\code{values_transform} instead.}\n\n\\item{names_transform, values_transform}{Optionally, a list of column\nname-function pairs. Alternatively, a single function can be supplied,\nwhich will be applied to all columns. Use these arguments if you need to\nchange the types of specific columns. For example, \\code{names_transform = list(week = as.integer)} would convert a character variable called \\code{week}\nto an integer.\n\nIf not specified, the type of the columns generated from \\code{names_to} will\nbe character, and the type of the variables generated from \\code{values_to}\nwill be the common type of the input columns used to generate them.}\n\n\\item{names_repair}{What happens if the output has invalid column names?\nThe default, \\code{\"check_unique\"} is to error if the columns are duplicated.\nUse \\code{\"minimal\"} to allow duplicates in the output, or \\code{\"unique\"} to\nde-duplicated by adding numeric suffixes. See \\code{\\link[vctrs:vec_as_names]{vctrs::vec_as_names()}}\nfor more options.}\n\n\\item{values_to}{A string specifying the name of the column to create\nfrom the data stored in cell values. If \\code{names_to} is a character\ncontaining the special \\code{.value} sentinel, this value will be ignored,\nand the name of the value column will be derived from part of the\nexisting column names.}\n\n\\item{values_drop_na}{If \\code{TRUE}, will drop rows that contain only \\code{NA}s\nin the \\code{values_to} column. This effectively converts explicit missing values\nto implicit missing values, and should generally be used only when missing\nvalues in \\code{data} were created by its structure.}\n\n\\item{...}{Additional arguments passed on to methods.}\n}\n\\value{\n`tidyseurat`\n}\n\\description{\n\\code{pivot_longer()} \"lengthens\" data, increasing the number of rows and\ndecreasing the number of columns. The inverse transformation is\n\\code{\\link[tidyr:pivot_wider]{pivot_wider()}}\n\nLearn more in \\code{vignette(\"pivot\")}.\n}\n\\details{\n\\code{pivot_longer()} is an updated approach to \\code{\\link[tidyr:gather]{gather()}}, designed to be both\nsimpler to use and to handle more use cases. We recommend you use\n\\code{pivot_longer()} for new code; \\code{gather()} isn't going away but is no longer\nunder active development.\n}\n\\examples{\ndata(pbmc_small)\npbmc_small |> pivot_longer(\n  cols=c(orig.ident, groups),\n  names_to=\"name\", values_to=\"value\")\n\n}\n"
  },
  {
    "path": "man/plotly.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/plotly_methods.R\n\\name{plotly}\n\\alias{plotly}\n\\alias{plot_ly}\n\\alias{plot_ly.tbl_df}\n\\alias{plot_ly.Seurat}\n\\title{Initiate a plotly visualization}\n\\usage{\nplot_ly(\n  data = data.frame(),\n  ...,\n  type = NULL,\n  name = NULL,\n  color = NULL,\n  colors = NULL,\n  alpha = NULL,\n  stroke = NULL,\n  strokes = NULL,\n  alpha_stroke = 1,\n  size = NULL,\n  sizes = c(10, 100),\n  span = NULL,\n  spans = c(1, 20),\n  symbol = NULL,\n  symbols = NULL,\n  linetype = NULL,\n  linetypes = NULL,\n  split = NULL,\n  frame = NULL,\n  width = NULL,\n  height = NULL,\n  source = \"A\"\n)\n\n\\method{plot_ly}{tbl_df}(\n  data = data.frame(),\n  ...,\n  type = NULL,\n  name = NULL,\n  color = NULL,\n  colors = NULL,\n  alpha = NULL,\n  stroke = NULL,\n  strokes = NULL,\n  alpha_stroke = 1,\n  size = NULL,\n  sizes = c(10, 100),\n  span = NULL,\n  spans = c(1, 20),\n  symbol = NULL,\n  symbols = NULL,\n  linetype = NULL,\n  linetypes = NULL,\n  split = NULL,\n  frame = NULL,\n  width = NULL,\n  height = NULL,\n  source = \"A\"\n)\n\n\\method{plot_ly}{Seurat}(\n  data = data.frame(),\n  ...,\n  type = NULL,\n  name = NULL,\n  color = NULL,\n  colors = NULL,\n  alpha = NULL,\n  stroke = NULL,\n  strokes = NULL,\n  alpha_stroke = 1,\n  size = NULL,\n  sizes = c(10, 100),\n  span = NULL,\n  spans = c(1, 20),\n  symbol = NULL,\n  symbols = NULL,\n  linetype = NULL,\n  linetypes = NULL,\n  split = NULL,\n  frame = NULL,\n  width = NULL,\n  height = NULL,\n  source = \"A\"\n)\n}\n\\arguments{\n\\item{data}{A data frame (optional) or \\link[crosstalk:SharedData]{crosstalk::SharedData} object.}\n\n\\item{...}{Arguments (i.e., attributes) passed along to the trace \\code{type}.\nSee \\code{\\link[plotly:schema]{schema()}} for a list of acceptable attributes for a given trace \\code{type}\n(by going to \\code{traces} -> \\code{type} -> \\code{attributes}). Note that attributes\nprovided at this level may override other arguments\n(e.g. \\code{plot_ly(x = 1:10, y = 1:10, color = I(\"red\"), marker = list(color = \"blue\"))}).}\n\n\\item{type}{A character string specifying the trace type (e.g. \\code{\"scatter\"}, \\code{\"bar\"}, \\code{\"box\"}, etc).\nIf specified, it \\emph{always} creates a trace, otherwise}\n\n\\item{name}{Values mapped to the trace's name attribute. Since a trace can\nonly have one name, this argument acts very much like \\code{split} in that it\ncreates one trace for every unique value.}\n\n\\item{color}{Values mapped to relevant 'fill-color' attribute(s)\n(e.g. \\href{https://plotly.com/r/reference/#scatter-fillcolor}{fillcolor},\n\\href{https://plotly.com/r/reference/#scatter-marker-color}{marker.color},\n\\href{https://plotly.com/r/reference/#scatter-textfont-color}{textfont.color}, etc.).\nThe mapping from data values to color codes may be controlled using\n\\code{colors} and \\code{alpha}, or avoided altogether via \\code{\\link[=I]{I()}} (e.g., \\code{color = I(\"red\")}).\nAny color understood by \\code{\\link[grDevices:col2rgb]{grDevices::col2rgb()}} may be used in this way.}\n\n\\item{colors}{Either a colorbrewer2.org palette name (e.g. \"YlOrRd\" or \"Blues\"),\nor a vector of colors to interpolate in hexadecimal \"#RRGGBB\" format,\nor a color interpolation function like \\code{colorRamp()}.}\n\n\\item{alpha}{A number between 0 and 1 specifying the alpha channel applied to \\code{color}.\nDefaults to 0.5 when mapping to \\href{https://plotly.com/r/reference/#scatter-fillcolor}{fillcolor} and 1 otherwise.}\n\n\\item{stroke}{Similar to \\code{color}, but values are mapped to relevant 'stroke-color' attribute(s)\n(e.g., \\href{https://plotly.com/r/reference/#scatter-marker-line-color}{marker.line.color}\nand \\href{https://plotly.com/r/reference/#scatter-line-color}{line.color}\nfor filled polygons). If not specified, \\code{stroke} inherits from \\code{color}.}\n\n\\item{strokes}{Similar to \\code{colors}, but controls the \\code{stroke} mapping.}\n\n\\item{alpha_stroke}{Similar to \\code{alpha}, but applied to \\code{stroke}.}\n\n\\item{size}{(Numeric) values mapped to relevant 'fill-size' attribute(s)\n(e.g., \\href{https://plotly.com/r/reference/#scatter-marker-size}{marker.size},\n\\href{https://plotly.com/r/reference/#scatter-textfont-size}{textfont.size},\nand \\href{https://plotly.com/r/reference/#scatter-error_x-width}{error_x.width}).\nThe mapping from data values to symbols may be controlled using\n\\code{sizes}, or avoided altogether via \\code{\\link[=I]{I()}} (e.g., \\code{size = I(30)}).}\n\n\\item{sizes}{A numeric vector of length 2 used to scale \\code{size} to pixels.}\n\n\\item{span}{(Numeric) values mapped to relevant 'stroke-size' attribute(s)\n(e.g.,\n\\href{https://plotly.com/r/reference/#scatter-marker-line-width}{marker.line.width},\n\\href{https://plotly.com/r/reference/#scatter-line-width}{line.width} for filled polygons,\nand \\href{https://plotly.com/r/reference/#scatter-error_x-thickness}{error_x.thickness})\nThe mapping from data values to symbols may be controlled using\n\\code{spans}, or avoided altogether via \\code{\\link[=I]{I()}} (e.g., \\code{span = I(30)}).}\n\n\\item{spans}{A numeric vector of length 2 used to scale \\code{span} to pixels.}\n\n\\item{symbol}{(Discrete) values mapped to \\href{https://plotly.com/r/reference/#scatter-marker-symbol}{marker.symbol}.\nThe mapping from data values to symbols may be controlled using\n\\code{symbols}, or avoided altogether via \\code{\\link[=I]{I()}} (e.g., \\code{symbol = I(\"pentagon\")}).\nAny \\link{pch} value or \\href{https://plotly.com/r/reference/#scatter-marker-symbol}{symbol name} may be used in this way.}\n\n\\item{symbols}{A character vector of \\link{pch} values or \\href{https://plotly.com/r/reference/#scatter-marker-symbol}{symbol names}.}\n\n\\item{linetype}{(Discrete) values mapped to \\href{https://plotly.com/r/reference/#scatter-line-dash}{line.dash}.\nThe mapping from data values to symbols may be controlled using\n\\code{linetypes}, or avoided altogether via \\code{\\link[=I]{I()}} (e.g., \\code{linetype = I(\"dash\")}).\nAny \\code{lty} (see \\link{par}) value or \\href{https://plotly.com/r/reference/#scatter-line-dash}{dash name} may be used in this way.}\n\n\\item{linetypes}{A character vector of \\code{lty} values or \\href{https://plotly.com/r/reference/#scatter-line-dash}{dash names}}\n\n\\item{split}{(Discrete) values used to create multiple traces (one trace per value).}\n\n\\item{frame}{(Discrete) values used to create animation frames.}\n\n\\item{width}{Width in pixels (optional, defaults to automatic sizing).}\n\n\\item{height}{Height in pixels (optional, defaults to automatic sizing).}\n\n\\item{source}{a character string of length 1. Match the value of this string\nwith the source argument in \\code{\\link[plotly:event_data]{event_data()}} to retrieve the\nevent data corresponding to a specific plot (shiny apps can have multiple plots).}\n}\n\\value{\n`plotly`\n}\n\\description{\nThis function maps R objects to \\href{https://plotly.com/javascript/}{plotly.js},\nan (MIT licensed) web-based interactive charting library. It provides\nabstractions for doing common things (e.g. mapping data values to\nfill colors (via \\code{color}) or creating \\link[plotly]{animation}s (via \\code{frame})) and sets\nsome different defaults to make the interface feel more 'R-like'\n(i.e., closer to \\code{\\link[=plot]{plot()}} and \\code{\\link[ggplot2:qplot]{ggplot2::qplot()}}).\n}\n\\details{\nUnless \\code{type} is specified, this function just initiates a plotly\nobject with 'global' attributes that are passed onto downstream uses of\n\\code{\\link[plotly:add_trace]{add_trace()}} (or similar). A \\link{formula} must always be used when\nreferencing column name(s) in \\code{data} (e.g. \\code{plot_ly(mtcars, x = ~wt)}).\nFormulas are optional when supplying values directly, but they do\nhelp inform default axis/scale titles\n(e.g., \\code{plot_ly(x = mtcars$wt)} vs \\code{plot_ly(x = ~mtcars$wt)})\n}\n\\examples{\ndata(pbmc_small)\nplot_ly(pbmc_small)\n\n}\n\\references{\n\\url{https://plotly-r.com/overview.html}\n}\n\\seealso{\n\\itemize{\n\\item For initializing a plotly-geo object: \\code{\\link[plotly:plot_geo]{plot_geo()}}\n\\item For initializing a plotly-mapbox object: \\code{\\link[plotly:plot_mapbox]{plot_mapbox()}}\n\\item For translating a ggplot2 object to a plotly object: \\code{\\link[plotly:ggplotly]{ggplotly()}}\n\\item For modifying any plotly object: \\code{\\link[plotly:layout]{layout()}}, \\code{\\link[plotly:add_trace]{add_trace()}}, \\code{\\link[plotly:style]{style()}}\n\\item For linked brushing: \\code{\\link[plotly:highlight]{highlight()}}\n\\item For arranging multiple plots: \\code{\\link[plotly:subplot]{subplot()}}, \\code{\\link[crosstalk:bscols]{crosstalk::bscols()}}\n\\item For inspecting plotly objects: \\code{\\link[plotly:plotly_json]{plotly_json()}}\n\\item For quick, accurate, and searchable plotly.js reference: \\code{\\link[plotly:schema]{schema()}}\n}\n}\n\\author{\nCarson Sievert\n}\n"
  },
  {
    "path": "man/pull.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{pull}\n\\alias{pull}\n\\alias{pull.Seurat}\n\\title{Extract a single column}\n\\usage{\n\\method{pull}{Seurat}(.data, var = -1, name = NULL, ...)\n}\n\\arguments{\n\\item{.data}{A data frame, data frame extension (e.g. a tibble), or a\nlazy data frame (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{var}{A variable specified as:\n\\itemize{\n\\item a literal variable name\n\\item a positive integer, giving the position counting from the left\n\\item a negative integer, giving the position counting from the right.\n}\n\nThe default returns the last column (on the assumption that's the\ncolumn you've created most recently).\n\nThis argument is taken by expression and supports\n\\link[rlang:topic-inject]{quasiquotation} (you can unquote column\nnames and column locations).}\n\n\\item{name}{An optional parameter that specifies the column to be used\nas names for a named vector. Specified in a similar manner as \\code{var}.}\n\n\\item{...}{For use by methods.}\n}\n\\value{\nA vector the same size as \\code{.data}.\n}\n\\description{\n\\code{pull()} is similar to \\code{$}. It's mostly useful because it looks a little\nnicer in pipes, it also works with remote data frames, and it can optionally\nname the output.\n}\n\\section{Methods}{\n\n\nThis function is a \\strong{generic}, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nThe following methods are currently available in loaded packages:\n\\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"pull\")}.\n\n}\n\n\\examples{\ndata(pbmc_small)\npbmc_small |> pull(groups)\n\n}\n"
  },
  {
    "path": "man/quo_names.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/utilities.R\n\\name{quo_names}\n\\alias{quo_names}\n\\title{Convert array of quosure (e.g. c(col_a, col_b)) into character vector}\n\\usage{\nquo_names(v)\n}\n\\arguments{\n\\item{v}{A array of quosures (e.g. c(col_a, col_b))}\n}\n\\value{\nA character vector\n}\n\\description{\nConvert array of quosure (e.g. c(col_a, col_b)) into character vector\n}\n\\keyword{internal}\n"
  },
  {
    "path": "man/rename.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{rename}\n\\alias{rename}\n\\alias{rename.Seurat}\n\\title{Rename columns}\n\\usage{\n\\method{rename}{Seurat}(.data, ...)\n}\n\\arguments{\n\\item{.data}{A data frame, data frame extension (e.g. a tibble), or a\nlazy data frame (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{...}{For \\code{rename()}: <\\code{\\link[dplyr:dplyr_tidy_select]{tidy-select}}> Use\n\\code{new_name = old_name} to rename selected variables.\n\nFor \\code{rename_with()}: additional arguments passed onto \\code{.fn}.}\n}\n\\value{\nAn object of the same type as \\code{.data}. The output has the following\nproperties:\n\\itemize{\n\\item Rows are not affected.\n\\item Column names are changed; column order is preserved.\n\\item Data frame attributes are preserved.\n\\item Groups are updated to reflect new names.\n}\n}\n\\description{\n\\code{rename()} changes the names of individual variables using\n\\code{new_name = old_name} syntax; \\code{rename_with()} renames columns using a\nfunction.\n}\n\\section{Methods}{\n\n\nThis function is a \\strong{generic}, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nThe following methods are currently available in loaded packages:\n\\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"rename\")}.\n\n}\n\n\\examples{\ndata(pbmc_small)\npbmc_small |> rename(s_score=nFeature_RNA)\n\n}\n\\seealso{\nOther single table verbs: \n\\code{\\link{arrange}()},\n\\code{\\link{mutate}()},\n\\code{\\link{slice}()},\n\\code{\\link{summarise}()}\n}\n\\concept{single table verbs}\n"
  },
  {
    "path": "man/return_arguments_of.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/utilities.R\n\\name{return_arguments_of}\n\\alias{return_arguments_of}\n\\title{returns variables from an expression}\n\\usage{\nreturn_arguments_of(expression)\n}\n\\arguments{\n\\item{expression}{an expression}\n}\n\\value{\nlist of symbols\n}\n\\description{\nreturns variables from an expression\n}\n"
  },
  {
    "path": "man/right_join.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{right_join}\n\\alias{right_join}\n\\alias{right_join.Seurat}\n\\title{Mutating joins}\n\\usage{\n\\method{right_join}{Seurat}(x, y, by = NULL, copy = FALSE, suffix = c(\".x\", \".y\"), ...)\n}\n\\arguments{\n\\item{x, y}{A pair of data frames, data frame extensions (e.g. a tibble), or\nlazy data frames (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{by}{A join specification created with \\code{\\link[dplyr:join_by]{join_by()}}, or a character\nvector of variables to join by.\n\nIf \\code{NULL}, the default, \\verb{*_join()} will perform a natural join, using all\nvariables in common across \\code{x} and \\code{y}. A message lists the variables so\nthat you can check they're correct; suppress the message by supplying \\code{by}\nexplicitly.\n\nTo join on different variables between \\code{x} and \\code{y}, use a \\code{\\link[dplyr:join_by]{join_by()}}\nspecification. For example, \\code{join_by(a == b)} will match \\code{x$a} to \\code{y$b}.\n\nTo join by multiple variables, use a \\code{\\link[dplyr:join_by]{join_by()}} specification with\nmultiple expressions. For example, \\code{join_by(a == b, c == d)} will match\n\\code{x$a} to \\code{y$b} and \\code{x$c} to \\code{y$d}. If the column names are the same between\n\\code{x} and \\code{y}, you can shorten this by listing only the variable names, like\n\\code{join_by(a, c)}.\n\n\\code{\\link[dplyr:join_by]{join_by()}} can also be used to perform inequality, rolling, and overlap\njoins. See the documentation at \\link[dplyr:join_by]{?join_by} for details on\nthese types of joins.\n\nFor simple equality joins, you can alternatively specify a character vector\nof variable names to join by. For example, \\code{by = c(\"a\", \"b\")} joins \\code{x$a}\nto \\code{y$a} and \\code{x$b} to \\code{y$b}. If variable names differ between \\code{x} and \\code{y},\nuse a named character vector like \\code{by = c(\"x_a\" = \"y_a\", \"x_b\" = \"y_b\")}.\n\nTo perform a cross-join, generating all combinations of \\code{x} and \\code{y}, see\n\\code{\\link[dplyr:cross_join]{cross_join()}}.}\n\n\\item{copy}{If \\code{x} and \\code{y} are not from the same data source,\nand \\code{copy} is \\code{TRUE}, then \\code{y} will be copied into the\nsame src as \\code{x}.  This allows you to join tables across srcs, but\nit is a potentially expensive operation so you must opt into it.}\n\n\\item{suffix}{If there are non-joined duplicate variables in \\code{x} and\n\\code{y}, these suffixes will be added to the output to disambiguate them.\nShould be a character vector of length 2.}\n\n\\item{...}{Other parameters passed onto methods.}\n}\n\\value{\nAn object of the same type as \\code{x} (including the same groups). The order of\nthe rows and columns of \\code{x} is preserved as much as possible. The output has\nthe following properties:\n\\itemize{\n\\item The rows are affect by the join type.\n\\itemize{\n\\item \\code{inner_join()} returns matched \\code{x} rows.\n\\item \\code{left_join()} returns all \\code{x} rows.\n\\item \\code{right_join()}  returns matched of \\code{x} rows, followed by unmatched \\code{y} rows.\n\\item \\code{full_join()}  returns all \\code{x} rows, followed by unmatched \\code{y} rows.\n}\n\\item Output columns include all columns from \\code{x} and all non-key columns from\n\\code{y}. If \\code{keep = TRUE}, the key columns from \\code{y} are included as well.\n\\item If non-key columns in \\code{x} and \\code{y} have the same name, \\code{suffix}es are added\nto disambiguate. If \\code{keep = TRUE} and key columns in \\code{x} and \\code{y} have\nthe same name, \\code{suffix}es are added to disambiguate these as well.\n\\item If \\code{keep = FALSE}, output columns included in \\code{by} are coerced to their\ncommon type between \\code{x} and \\code{y}.\n}\n}\n\\description{\nMutating joins add columns from \\code{y} to \\code{x}, matching observations based on\nthe keys. There are four mutating joins: the inner join, and the three outer\njoins.\n\\subsection{Inner join}{\n\nAn \\code{inner_join()} only keeps observations from \\code{x} that have a matching key\nin \\code{y}.\n\nThe most important property of an inner join is that unmatched rows in either\ninput are not included in the result. This means that generally inner joins\nare not appropriate in most analyses, because it is too easy to lose\nobservations.\n}\n\n\\subsection{Outer joins}{\n\nThe three outer joins keep observations that appear in at least one of the\ndata frames:\n\\itemize{\n\\item A \\code{left_join()} keeps all observations in \\code{x}.\n\\item A \\code{right_join()} keeps all observations in \\code{y}.\n\\item A \\code{full_join()} keeps all observations in \\code{x} and \\code{y}.\n}\n}\n}\n\\section{Many-to-many relationships}{\n\n\n\nBy default, dplyr guards against many-to-many relationships in equality joins\nby throwing a warning. These occur when both of the following are true:\n\\itemize{\n\\item A row in \\code{x} matches multiple rows in \\code{y}.\n\\item A row in \\code{y} matches multiple rows in \\code{x}.\n}\n\nThis is typically surprising, as most joins involve a relationship of\none-to-one, one-to-many, or many-to-one, and is often the result of an\nimproperly specified join. Many-to-many relationships are particularly\nproblematic because they can result in a Cartesian explosion of the number of\nrows returned from the join.\n\nIf a many-to-many relationship is expected, silence this warning by\nexplicitly setting \\code{relationship = \"many-to-many\"}.\n\nIn production code, it is best to preemptively set \\code{relationship} to whatever\nrelationship you expect to exist between the keys of \\code{x} and \\code{y}, as this\nforces an error to occur immediately if the data doesn't align with your\nexpectations.\n\nInequality joins typically result in many-to-many relationships by nature, so\nthey don't warn on them by default, but you should still take extra care when\nspecifying an inequality join, because they also have the capability to\nreturn a large number of rows.\n\nRolling joins don't warn on many-to-many relationships either, but many\nrolling joins follow a many-to-one relationship, so it is often useful to\nset \\code{relationship = \"many-to-one\"} to enforce this.\n\nNote that in SQL, most database providers won't let you specify a\nmany-to-many relationship between two tables, instead requiring that you\ncreate a third \\emph{junction table} that results in two one-to-many relationships\ninstead.\n\n}\n\n\\section{Methods}{\n\n\nThese functions are \\strong{generic}s, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nMethods available in currently loaded packages:\n\\itemize{\n\\item \\code{inner_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"inner_join\")}.\n\\item \\code{left_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"left_join\")}.\n\\item \\code{right_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"right_join\")}.\n\\item \\code{full_join()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"full_join\")}.\n}\n\n}\n\n\\examples{\ndata(pbmc_small)\ntt <- pbmc_small\ntt |> right_join(tt |> \n  distinct(groups) |> \n  mutate(new_column=1:2) |> \n  slice(1))\n\n}\n\\seealso{\nOther joins: \n\\code{\\link[dplyr]{cross_join}()},\n\\code{\\link[dplyr]{filter-joins}},\n\\code{\\link[dplyr]{nest_join}()}\n}\n"
  },
  {
    "path": "man/rowwise.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{rowwise}\n\\alias{rowwise}\n\\alias{rowwise.Seurat}\n\\title{Group input by rows}\n\\usage{\n\\method{rowwise}{Seurat}(data, ...)\n}\n\\arguments{\n\\item{data}{Input data frame.}\n\n\\item{...}{<\\code{\\link[dplyr:dplyr_tidy_select]{tidy-select}}> Variables to be preserved\nwhen calling \\code{\\link[dplyr:summarise]{summarise()}}. This is typically a set of variables whose\ncombination uniquely identify each row.\n\n\\strong{NB}: unlike \\code{group_by()} you can not create new variables here but\ninstead you can select multiple variables with (e.g.) \\code{everything()}.}\n}\n\\value{\nA row-wise data frame with class \\code{rowwise_df}. Note that a\n\\code{rowwise_df} is implicitly grouped by row, but is not a \\code{grouped_df}.\n}\n\\description{\n\\code{rowwise()} allows you to compute on a data frame a row-at-a-time.\nThis is most useful when a vectorised function doesn't exist.\n\nMost dplyr verbs preserve row-wise grouping. The exception is \\code{\\link[dplyr:summarise]{summarise()}},\nwhich return a \\link[dplyr]{grouped_df}. You can explicitly ungroup with \\code{\\link[dplyr:ungroup]{ungroup()}}\nor \\code{\\link[dplyr:as_tibble]{as_tibble()}}, or convert to a \\link[dplyr]{grouped_df} with \\code{\\link[dplyr:group_by]{group_by()}}.\n}\n\\section{List-columns}{\n\n\nBecause a rowwise has exactly one row per group it offers a small\nconvenience for working with list-columns. Normally, \\code{summarise()} and\n\\code{mutate()} extract a groups worth of data with \\code{[}. But when you index\na list in this way, you get back another list. When you're working with\na \\code{rowwise} tibble, then dplyr will use \\code{[[} instead of \\code{[} to make your\nlife a little easier.\n\n}\n\n\\examples{\n# TODO\n\n}\n\\seealso{\n\\code{\\link[dplyr:nest_by]{nest_by()}} for a convenient way of creating rowwise data frames\nwith nested data.\n}\n"
  },
  {
    "path": "man/sample_n.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{sample_n}\n\\alias{sample_n}\n\\alias{sample_n.Seurat}\n\\alias{sample_frac}\n\\alias{sample_frac.Seurat}\n\\title{Sample n rows from a table}\n\\usage{\n\\method{sample_n}{Seurat}(tbl, size, replace = FALSE, weight = NULL, .env = NULL, ...)\n\n\\method{sample_frac}{Seurat}(tbl, size = 1, replace = FALSE, weight = NULL, .env = NULL, ...)\n}\n\\arguments{\n\\item{tbl}{A data.frame.}\n\n\\item{size}{<\\code{\\link[dplyr:dplyr_tidy_select]{tidy-select}}>\nFor \\code{sample_n()}, the number of rows to select.\nFor \\code{sample_frac()}, the fraction of rows to select.\nIf \\code{tbl} is grouped, \\code{size} applies to each group.}\n\n\\item{replace}{Sample with or without replacement?}\n\n\\item{weight}{<\\code{\\link[dplyr:dplyr_tidy_select]{tidy-select}}> Sampling weights.\nThis must evaluate to a vector of non-negative numbers the same length as\nthe input. Weights are automatically standardised to sum to 1.}\n\n\\item{.env}{DEPRECATED.}\n\n\\item{...}{ignored}\n}\n\\description{\n\\ifelse{html}{\\href{https://lifecycle.r-lib.org/articles/stages.html#superseded}{\\figure{lifecycle-superseded.svg}{options: alt='[Superseded]'}}}{\\strong{[Superseded]}}\n\\code{sample_n()} and \\code{sample_frac()} have been superseded in favour of\n\\code{\\link[dplyr:slice_sample]{slice_sample()}}. While they will not be deprecated in the near future,\nretirement means that we will only perform critical bug fixes, so we recommend\nmoving to the newer alternative.\n\nThese functions were superseded because we realised it was more convenient to\nhave two mutually exclusive arguments to one function, rather than two\nseparate functions. This also made it to clean up a few other smaller\ndesign issues with \\code{sample_n()}/\\code{sample_frac}:\n\\itemize{\n\\item The connection to \\code{slice()} was not obvious.\n\\item The name of the first argument, \\code{tbl}, is inconsistent with other\nsingle table verbs which use \\code{.data}.\n\\item The \\code{size} argument uses tidy evaluation, which is surprising and\nundocumented.\n\\item It was easier to remove the deprecated \\code{.env} argument.\n\\item \\code{...} was in a suboptimal position.\n}\n}\n\\examples{\ndata(pbmc_small)\npbmc_small |> sample_n(50)\npbmc_small |> sample_frac(0.1)\n\n}\n"
  },
  {
    "path": "man/select.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{select}\n\\alias{select}\n\\alias{select.Seurat}\n\\title{Keep or drop columns using their names and types}\n\\usage{\n\\method{select}{Seurat}(.data, ...)\n}\n\\arguments{\n\\item{.data}{A data frame, data frame extension (e.g. a tibble), or a\nlazy data frame (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{...}{<\\code{\\link[dplyr:dplyr_tidy_select]{tidy-select}}> One or more unquoted\nexpressions separated by commas. Variable names can be used as if they\nwere positions in the data frame, so expressions like \\code{x:y} can\nbe used to select a range of variables.}\n}\n\\value{\nAn object of the same type as \\code{.data}. The output has the following\nproperties:\n\\itemize{\n\\item Rows are not affected.\n\\item Output columns are a subset of input columns, potentially with a different\norder. Columns will be renamed if \\code{new_name = old_name} form is used.\n\\item Data frame attributes are preserved.\n\\item Groups are maintained; you can't select off grouping variables.\n}\n}\n\\description{\nSelect (and optionally rename) variables in a data frame, using a concise\nmini-language that makes it easy to refer to variables based on their name\n(e.g. \\code{a:f} selects all columns from \\code{a} on the left to \\code{f} on the\nright) or type (e.g. \\code{where(is.numeric)} selects all numeric columns).\n\\subsection{Overview of selection features}{\n\nTidyverse selections implement a dialect of R where operators make\nit easy to select variables:\n\\itemize{\n\\item \\code{:} for selecting a range of consecutive variables.\n\\item \\code{!} for taking the complement of a set of variables.\n\\item \\code{&} and \\code{|} for selecting the intersection or the union of two\nsets of variables.\n\\item \\code{c()} for combining selections.\n}\n\nIn addition, you can use \\strong{selection helpers}. Some helpers select specific\ncolumns:\n\\itemize{\n\\item \\code{\\link[tidyselect:everything]{everything()}}: Matches all variables.\n\\item \\code{\\link[tidyselect:everything]{last_col()}}: Select last variable, possibly with an offset.\n\\item \\code{\\link[dplyr:group_cols]{group_cols()}}: Select all grouping columns.\n}\n\nOther helpers select variables by matching patterns in their names:\n\\itemize{\n\\item \\code{\\link[tidyselect:starts_with]{starts_with()}}: Starts with a prefix.\n\\item \\code{\\link[tidyselect:starts_with]{ends_with()}}: Ends with a suffix.\n\\item \\code{\\link[tidyselect:starts_with]{contains()}}: Contains a literal string.\n\\item \\code{\\link[tidyselect:starts_with]{matches()}}: Matches a regular expression.\n\\item \\code{\\link[tidyselect:starts_with]{num_range()}}: Matches a numerical range like x01, x02, x03.\n}\n\nOr from variables stored in a character vector:\n\\itemize{\n\\item \\code{\\link[tidyselect:all_of]{all_of()}}: Matches variable names in a character vector. All\nnames must be present, otherwise an out-of-bounds error is\nthrown.\n\\item \\code{\\link[tidyselect:all_of]{any_of()}}: Same as \\code{all_of()}, except that no error is thrown\nfor names that don't exist.\n}\n\nOr using a predicate function:\n\\itemize{\n\\item \\code{\\link[tidyselect:where]{where()}}: Applies a function to all variables and selects those\nfor which the function returns \\code{TRUE}.\n}\n}\n}\n\\section{Methods}{\n\n\nThis function is a \\strong{generic}, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nThe following methods are currently available in loaded packages:\n\\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"select\")}.\n\n}\n\n\\section{Examples}{\n\n\n\nHere we show the usage for the basic selection operators. See the\nspecific help pages to learn about helpers like \\code{\\link[dplyr:starts_with]{starts_with()}}.\n\nThe selection language can be used in functions like\n\\code{dplyr::select()}. Let's first attach\nthe tidyverse:\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{library(tidyverse)\n\n# For better printing\niris <- as_tibble(iris)\n}\\if{html}{\\out{</div>}}\n\nSelect variables by name:\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{starwars |> select(height)\n#> # A tibble: 87 x 1\n#>   height\n#>    <int>\n#> 1    172\n#> 2    167\n#> 3     96\n#> 4    202\n#> # i 83 more rows\n\niris |> select(Sepal.Length)\n#> # A tibble: 150 x 1\n#>   Sepal.Length\n#>          <dbl>\n#> 1          5.1\n#> 2          4.9\n#> 3          4.7\n#> 4          4.6\n#> # i 146 more rows\n}\\if{html}{\\out{</div>}}\n\nSelect multiple variables by separating them with commas. Note how\nthe order of columns is determined by the order of inputs:\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{starwars |> select(homeworld, height, mass)\n#> # A tibble: 87 x 3\n#>   homeworld height  mass\n#>   <chr>      <int> <dbl>\n#> 1 Tatooine     172    77\n#> 2 Tatooine     167    75\n#> 3 Naboo         96    32\n#> 4 Tatooine     202   136\n#> # i 83 more rows\n\niris |> select(Sepal.Length, Petal.Length)\n#> # A tibble: 150 x 2\n#>   Sepal.Length Petal.Length\n#>          <dbl>        <dbl>\n#> 1          5.1          1.4\n#> 2          4.9          1.4\n#> 3          4.7          1.3\n#> 4          4.6          1.5\n#> # i 146 more rows\n}\\if{html}{\\out{</div>}}\n\nIf you use a named vector to select columns, the output will have\nits columns renamed:\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{selection <- c(\n  new_homeworld = \"homeworld\",\n  new_height = \"height\",\n  new_mass = \"mass\"\n)\nstarwars |> select(all_of(selection))\n#> # A tibble: 87 x 3\n#>   new_homeworld new_height new_mass\n#>   <chr>              <int>    <dbl>\n#> 1 Tatooine             172       77\n#> 2 Tatooine             167       75\n#> 3 Naboo                 96       32\n#> 4 Tatooine             202      136\n#> # i 83 more rows\n}\\if{html}{\\out{</div>}}\n\\subsection{Operators:}{\n\nThe \\code{:} operator selects a range of consecutive variables:\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{starwars |> select(name:mass)\n#> # A tibble: 87 x 3\n#>   name           height  mass\n#>   <chr>           <int> <dbl>\n#> 1 Luke Skywalker    172    77\n#> 2 C-3PO             167    75\n#> 3 R2-D2              96    32\n#> 4 Darth Vader       202   136\n#> # i 83 more rows\n}\\if{html}{\\out{</div>}}\n\nThe \\code{!} operator negates a selection:\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{starwars |> select(!(name:mass))\n#> # A tibble: 87 x 11\n#>   hair_color skin_color  eye_color birth_year sex   gender    homeworld species\n#>   <chr>      <chr>       <chr>          <dbl> <chr> <chr>     <chr>     <chr>  \n#> 1 blond      fair        blue            19   male  masculine Tatooine  Human  \n#> 2 <NA>       gold        yellow         112   none  masculine Tatooine  Droid  \n#> 3 <NA>       white, blue red             33   none  masculine Naboo     Droid  \n#> 4 none       white       yellow          41.9 male  masculine Tatooine  Human  \n#> # i 83 more rows\n#> # i 3 more variables: films <list>, vehicles <list>, starships <list>\n\niris |> select(!c(Sepal.Length, Petal.Length))\n#> # A tibble: 150 x 3\n#>   Sepal.Width Petal.Width Species\n#>         <dbl>       <dbl> <fct>  \n#> 1         3.5         0.2 setosa \n#> 2         3           0.2 setosa \n#> 3         3.2         0.2 setosa \n#> 4         3.1         0.2 setosa \n#> # i 146 more rows\n\niris |> select(!ends_with(\"Width\"))\n#> # A tibble: 150 x 3\n#>   Sepal.Length Petal.Length Species\n#>          <dbl>        <dbl> <fct>  \n#> 1          5.1          1.4 setosa \n#> 2          4.9          1.4 setosa \n#> 3          4.7          1.3 setosa \n#> 4          4.6          1.5 setosa \n#> # i 146 more rows\n}\\if{html}{\\out{</div>}}\n\n\\code{&} and \\code{|} take the intersection or the union of two selections:\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{iris |> select(starts_with(\"Petal\") & ends_with(\"Width\"))\n#> # A tibble: 150 x 1\n#>   Petal.Width\n#>         <dbl>\n#> 1         0.2\n#> 2         0.2\n#> 3         0.2\n#> 4         0.2\n#> # i 146 more rows\n\niris |> select(starts_with(\"Petal\") | ends_with(\"Width\"))\n#> # A tibble: 150 x 3\n#>   Petal.Length Petal.Width Sepal.Width\n#>          <dbl>       <dbl>       <dbl>\n#> 1          1.4         0.2         3.5\n#> 2          1.4         0.2         3  \n#> 3          1.3         0.2         3.2\n#> 4          1.5         0.2         3.1\n#> # i 146 more rows\n}\\if{html}{\\out{</div>}}\n\nTo take the difference between two selections, combine the \\code{&} and\n\\code{!} operators:\n\n\\if{html}{\\out{<div class=\"sourceCode r\">}}\\preformatted{iris |> select(starts_with(\"Petal\") & !ends_with(\"Width\"))\n#> # A tibble: 150 x 1\n#>   Petal.Length\n#>          <dbl>\n#> 1          1.4\n#> 2          1.4\n#> 3          1.3\n#> 4          1.5\n#> # i 146 more rows\n}\\if{html}{\\out{</div>}}\n}\n\n}\n\n\\examples{\ndata(pbmc_small)\npbmc_small |> select(cell, orig.ident)\n\n}\n\\seealso{\nOther single table verbs: \n\\code{\\link[dplyr]{arrange}()},\n\\code{\\link[dplyr]{filter}()},\n\\code{\\link[dplyr]{mutate}()},\n\\code{\\link[dplyr]{reframe}()},\n\\code{\\link[dplyr]{rename}()},\n\\code{\\link[dplyr]{slice}()},\n\\code{\\link[dplyr]{summarise}()}\n}\n"
  },
  {
    "path": "man/separate.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/tidyr_methods.R\n\\name{separate}\n\\alias{separate}\n\\alias{separate.Seurat}\n\\title{Separate a character column into multiple columns with a regular\nexpression or numeric locations}\n\\usage{\n\\method{separate}{Seurat}(\n  data,\n  col,\n  into,\n  sep = \"[^[:alnum:]]+\",\n  remove = TRUE,\n  convert = FALSE,\n  extra = \"warn\",\n  fill = \"warn\",\n  ...\n)\n}\n\\arguments{\n\\item{data}{A data frame.}\n\n\\item{col}{<\\code{\\link[tidyr:tidyr_tidy_select]{tidy-select}}> Column to expand.}\n\n\\item{into}{Names of new variables to create as character vector.\nUse \\code{NA} to omit the variable in the output.}\n\n\\item{sep}{Separator between columns.\n\nIf character, \\code{sep} is interpreted as a regular expression. The default\nvalue is a regular expression that matches any sequence of\nnon-alphanumeric values.\n\nIf numeric, \\code{sep} is interpreted as character positions to split at. Positive\nvalues start at 1 at the far-left of the string; negative value start at -1 at\nthe far-right of the string. The length of \\code{sep} should be one less than\n\\code{into}.}\n\n\\item{remove}{If \\code{TRUE}, remove input column from output data frame.}\n\n\\item{convert}{If \\code{TRUE}, will run \\code{\\link[=type.convert]{type.convert()}} with\n\\code{as.is = TRUE} on new columns. This is useful if the component\ncolumns are integer, numeric or logical.\n\nNB: this will cause string \\code{\"NA\"}s to be converted to \\code{NA}s.}\n\n\\item{extra}{If \\code{sep} is a character vector, this controls what\nhappens when there are too many pieces. There are three valid options:\n\\itemize{\n\\item \\code{\"warn\"} (the default): emit a warning and drop extra values.\n\\item \\code{\"drop\"}: drop any extra values without a warning.\n\\item \\code{\"merge\"}: only splits at most \\code{length(into)} times\n}}\n\n\\item{fill}{If \\code{sep} is a character vector, this controls what\nhappens when there are not enough pieces. There are three valid options:\n\\itemize{\n\\item \\code{\"warn\"} (the default): emit a warning and fill from the right\n\\item \\code{\"right\"}: fill with missing values on the right\n\\item \\code{\"left\"}: fill with missing values on the left\n}}\n\n\\item{...}{Additional arguments passed on to methods.}\n}\n\\value{\n`tidyseurat`\n}\n\\description{\n\\ifelse{html}{\\href{https://lifecycle.r-lib.org/articles/stages.html#superseded}{\\figure{lifecycle-superseded.svg}{options: alt='[Superseded]'}}}{\\strong{[Superseded]}}\n\n\\code{separate()} has been superseded in favour of \\code{\\link[tidyr:separate_wider_position]{separate_wider_position()}}\nand \\code{\\link[tidyr:separate_wider_delim]{separate_wider_delim()}} because the two functions make the two uses\nmore obvious, the API is more polished, and the handling of problems is\nbetter. Superseded functions will not go away, but will only receive\ncritical bug fixes.\n\nGiven either a regular expression or a vector of character positions,\n\\code{separate()} turns a single character column into multiple columns.\n}\n\\examples{\ndata(pbmc_small)\nun <- pbmc_small |> unite(\"new_col\", c(orig.ident, groups))\nun |> separate(new_col, c(\"orig.ident\", \"groups\"))\n\n}\n\\seealso{\n\\code{\\link[tidyr:unite]{unite()}}, the complement, \\code{\\link[tidyr:extract]{extract()}} which uses regular\nexpression capturing groups.\n}\n"
  },
  {
    "path": "man/slice.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{slice}\n\\alias{slice}\n\\alias{slice.Seurat}\n\\alias{slice_head}\n\\alias{slice_tail}\n\\alias{slice_sample}\n\\alias{slice_min}\n\\alias{slice_max}\n\\alias{slice_sample.Seurat}\n\\alias{slice_head.Seurat}\n\\alias{slice_tail.Seurat}\n\\alias{slice_min.Seurat}\n\\alias{slice_max.Seurat}\n\\title{Subset rows using their positions}\n\\usage{\n\\method{slice}{Seurat}(.data, ..., .by = NULL, .preserve = FALSE)\n\n\\method{slice_sample}{Seurat}(\n  .data,\n  ...,\n  n = NULL,\n  prop = NULL,\n  by = NULL,\n  weight_by = NULL,\n  replace = FALSE\n)\n\n\\method{slice_head}{Seurat}(.data, ..., n, prop, by = NULL)\n\n\\method{slice_tail}{Seurat}(.data, ..., n, prop, by = NULL)\n\n\\method{slice_min}{Seurat}(\n  .data,\n  order_by,\n  ...,\n  n,\n  prop,\n  by = NULL,\n  with_ties = TRUE,\n  na_rm = FALSE\n)\n\n\\method{slice_max}{Seurat}(\n  .data,\n  order_by,\n  ...,\n  n,\n  prop,\n  by = NULL,\n  with_ties = TRUE,\n  na_rm = FALSE\n)\n}\n\\arguments{\n\\item{.data}{A data frame, data frame extension (e.g. a tibble), or a\nlazy data frame (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{...}{For \\code{slice()}: <\\code{\\link[rlang:args_data_masking]{data-masking}}>\nInteger row values.\n\nProvide either positive values to keep, or negative values to drop.\nThe values provided must be either all positive or all negative.\nIndices beyond the number of rows in the input are silently ignored.\n\nFor \\verb{slice_*()}, these arguments are passed on to methods.}\n\n\\item{.by, by}{<\\code{\\link[dplyr:dplyr_tidy_select]{tidy-select}}> Optionally, a selection of columns to\ngroup by for just this operation, functioning as an alternative to \\code{\\link[dplyr:group_by]{group_by()}}. For\ndetails and examples, see \\link[dplyr:dplyr_by]{?dplyr_by}.}\n\n\\item{.preserve}{Relevant when the \\code{.data} input is grouped. If \\code{.preserve = FALSE} (the default), the grouping structure is recalculated based on the\nresulting data, otherwise the grouping is kept as is.}\n\n\\item{n, prop}{Provide either \\code{n}, the number of rows, or \\code{prop}, the\nproportion of rows to select. If neither are supplied, \\code{n = 1} will be\nused. If \\code{n} is greater than the number of rows in the group\n(or \\code{prop > 1}), the result will be silently truncated to the group size.\n\\code{prop} will be rounded towards zero to generate an integer number of\nrows.\n\nA negative value of \\code{n} or \\code{prop} will be subtracted from the group\nsize. For example, \\code{n = -2} with a group of 5 rows will select 5 - 2 = 3\nrows; \\code{prop = -0.25} with 8 rows will select 8 * (1 - 0.25) = 6 rows.}\n\n\\item{weight_by}{<\\code{\\link[rlang:args_data_masking]{data-masking}}> Sampling\nweights. This must evaluate to a vector of non-negative numbers the same\nlength as the input. Weights are automatically standardised to sum to 1.\nSee the \\code{Details} section for more technical details regarding these\nweights.}\n\n\\item{replace}{Should sampling be performed with (\\code{TRUE}) or without\n(\\code{FALSE}, the default) replacement.}\n\n\\item{order_by}{<\\code{\\link[rlang:args_data_masking]{data-masking}}> Variable or\nfunction of variables to order by. To order by multiple variables, wrap\nthem in a data frame or tibble.}\n\n\\item{with_ties}{Should ties be kept together? The default, \\code{TRUE},\nmay return more rows than you request. Use \\code{FALSE} to ignore ties,\nand return the first \\code{n} rows.}\n\n\\item{na_rm}{Should missing values in \\code{order_by} be removed from the result?\nIf \\code{FALSE}, \\code{NA} values are sorted to the end (like in \\code{\\link[dplyr:arrange]{arrange()}}), so\nthey will only be included if there are insufficient non-missing values to\nreach \\code{n}/\\code{prop}.}\n}\n\\value{\nAn object of the same type as \\code{.data}. The output has the following\nproperties:\n\\itemize{\n\\item Each row may appear 0, 1, or many times in the output.\n\\item Columns are not modified.\n\\item Groups are not modified.\n\\item Data frame attributes are preserved.\n}\n}\n\\description{\n\\code{slice()} lets you index rows by their (integer) locations. It allows you\nto select, remove, and duplicate rows. It is accompanied by a number of\nhelpers for common use cases:\n\\itemize{\n\\item \\code{slice_head()} and \\code{slice_tail()} select the first or last rows.\n\\item \\code{slice_sample()} randomly selects rows.\n\\item \\code{slice_min()} and \\code{slice_max()} select rows with the smallest or largest\nvalues of a variable.\n}\n\nIf \\code{.data} is a \\link[dplyr]{grouped_df}, the operation will be performed on each group,\nso that (e.g.) \\code{slice_head(df, n = 5)} will select the first five rows in\neach group.\n}\n\\details{\nSlice does not work with relational databases because they have no\nintrinsic notion of row order. If you want to perform the equivalent\noperation, use \\code{\\link[dplyr:filter]{filter()}} and \\code{\\link[dplyr:row_number]{row_number()}}.\n\nFor \\code{slice_sample()}, note that the weights provided in \\code{weight_by} are\npassed through to the \\code{prob} argument of \\code{\\link[base:sample]{base::sample.int()}}. This means\nthey cannot be used to reconstruct summary statistics from the underlying\npopulation. See \\href{https://stats.stackexchange.com/q/639211/}{this discussion}\nfor more details.\n}\n\\section{Methods}{\n\n\nThese function are \\strong{generic}s, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nMethods available in currently loaded packages:\n\\itemize{\n\\item \\code{slice()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice\")}.\n\\item \\code{slice_head()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_head\")}.\n\\item \\code{slice_tail()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_tail\")}.\n\\item \\code{slice_min()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_min\")}.\n\\item \\code{slice_max()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_max\")}.\n\\item \\code{slice_sample()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_sample\")}.\n}\n\n\n\n\nThese function are \\strong{generic}s, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nMethods available in currently loaded packages:\n\\itemize{\n\\item \\code{slice()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice\")}.\n\\item \\code{slice_head()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_head\")}.\n\\item \\code{slice_tail()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_tail\")}.\n\\item \\code{slice_min()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_min\")}.\n\\item \\code{slice_max()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_max\")}.\n\\item \\code{slice_sample()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_sample\")}.\n}\n\n\n\n\nThese function are \\strong{generic}s, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nMethods available in currently loaded packages:\n\\itemize{\n\\item \\code{slice()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice\")}.\n\\item \\code{slice_head()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_head\")}.\n\\item \\code{slice_tail()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_tail\")}.\n\\item \\code{slice_min()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_min\")}.\n\\item \\code{slice_max()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_max\")}.\n\\item \\code{slice_sample()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_sample\")}.\n}\n\n\n\n\nThese function are \\strong{generic}s, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nMethods available in currently loaded packages:\n\\itemize{\n\\item \\code{slice()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice\")}.\n\\item \\code{slice_head()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_head\")}.\n\\item \\code{slice_tail()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_tail\")}.\n\\item \\code{slice_min()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_min\")}.\n\\item \\code{slice_max()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_max\")}.\n\\item \\code{slice_sample()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_sample\")}.\n}\n\n\n\n\nThese function are \\strong{generic}s, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nMethods available in currently loaded packages:\n\\itemize{\n\\item \\code{slice()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice\")}.\n\\item \\code{slice_head()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_head\")}.\n\\item \\code{slice_tail()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_tail\")}.\n\\item \\code{slice_min()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_min\")}.\n\\item \\code{slice_max()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_max\")}.\n\\item \\code{slice_sample()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_sample\")}.\n}\n\n\n\n\nThese function are \\strong{generic}s, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nMethods available in currently loaded packages:\n\\itemize{\n\\item \\code{slice()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice\")}.\n\\item \\code{slice_head()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_head\")}.\n\\item \\code{slice_tail()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_tail\")}.\n\\item \\code{slice_min()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_min\")}.\n\\item \\code{slice_max()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_max\")}.\n\\item \\code{slice_sample()}: \\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"slice_sample\")}.\n}\n\n}\n\n\\examples{\ndata(pbmc_small)\npbmc_small |> slice(1)\n\n# Slice group-wise using .by\npbmc_small |> slice(1:2, .by=groups)\n\n\n# slice_sample() allows you to random select with or without replacement\npbmc_small |> slice_sample(n=5)\n\n# if using replacement, and duplicate cells are returned, a tibble will be\n# returned because duplicate cells cannot exist in Seurat objects\npbmc_small |> slice_sample(n=1, replace=TRUE) # returns Seurat\npbmc_small |> slice_sample(n=100, replace=TRUE) # returns tibble\n\n# weight by a variable\npbmc_small |> slice_sample(n=5, weight_by=nCount_RNA)\n\n# sample by group\npbmc_small |> slice_sample(n=5, by=groups)\n\n# sample using proportions\npbmc_small |> slice_sample(prop=0.10)\n\n\n# First rows based on existing order\npbmc_small |> slice_head(n=5)\n\n\n# Last rows based on existing order\npbmc_small |> slice_tail(n=5)\n\n\n# Rows with minimum and maximum values of a metadata variable\npbmc_small |> slice_min(nFeature_RNA, n=5)\n\n# slice_min() and slice_max() may return more rows than requested\n# in the presence of ties.\npbmc_small |>  slice_min(nFeature_RNA, n=2)\n\n# Use with_ties=FALSE to return exactly n matches\npbmc_small |> slice_min(nFeature_RNA, n=2, with_ties=FALSE)\n\n# Or use additional variables to break the tie:\npbmc_small |> slice_min(tibble::tibble(nFeature_RNA, nCount_RNA), n=2)\n\n# Use by for group-wise operations\npbmc_small |> slice_min(nFeature_RNA, n=5, by=groups)\n\n\n# Rows with minimum and maximum values of a metadata variable\npbmc_small |> slice_max(nFeature_RNA, n=5)\n\n}\n\\seealso{\nOther single table verbs: \n\\code{\\link{arrange}()},\n\\code{\\link{mutate}()},\n\\code{\\link{rename}()},\n\\code{\\link{summarise}()}\n}\n\\concept{single table verbs}\n"
  },
  {
    "path": "man/summarise.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/dplyr_methods.R\n\\name{summarise}\n\\alias{summarise}\n\\alias{summarise.Seurat}\n\\alias{summarize}\n\\alias{summarize.Seurat}\n\\title{Summarise each group down to one row}\n\\usage{\n\\method{summarise}{Seurat}(.data, ...)\n\n\\method{summarize}{Seurat}(.data, ...)\n}\n\\arguments{\n\\item{.data}{A data frame, data frame extension (e.g. a tibble), or a\nlazy data frame (e.g. from dbplyr or dtplyr). See \\emph{Methods}, below, for\nmore details.}\n\n\\item{...}{<\\code{\\link[rlang:args_data_masking]{data-masking}}> Name-value pairs of\nsummary functions. The name will be the name of the variable in the result.\n\nThe value can be:\n\\itemize{\n\\item A vector of length 1, e.g. \\code{min(x)}, \\code{n()}, or \\code{sum(is.na(y))}.\n\\item A data frame with 1 row, to add multiple columns from a single expression.\n}}\n}\n\\value{\nAn object \\emph{usually} of the same type as \\code{.data}.\n\\itemize{\n\\item The rows come from the underlying \\code{\\link[dplyr:group_keys]{group_keys()}}.\n\\item The columns are a combination of the grouping keys and the summary\nexpressions that you provide.\n\\item The grouping structure is controlled by the \\verb{.groups=} argument, the\noutput may be another \\link[dplyr]{grouped_df}, a \\link[dplyr]{tibble} or a \\link[dplyr]{rowwise} data frame.\n\\item Data frame attributes are \\strong{not} preserved, because \\code{summarise()}\nfundamentally creates a new data frame.\n}\n}\n\\description{\n\\code{summarise()} creates a new data frame. It returns one row for each\ncombination of grouping variables; if there are no grouping variables, the\noutput will have a single row summarising all observations in the input. It\nwill contain one column for each grouping variable and one column for each of\nthe summary statistics that you have specified.\n\n\\code{summarise()} and \\code{summarize()} are synonyms.\n}\n\\section{Useful functions}{\n\n\n\\itemize{\n\\item Center: \\code{\\link[=mean]{mean()}}, \\code{\\link[=median]{median()}}\n\\item Spread: \\code{\\link[=sd]{sd()}}, \\code{\\link[=IQR]{IQR()}}, \\code{\\link[=mad]{mad()}}\n\\item Range: \\code{\\link[=min]{min()}}, \\code{\\link[=max]{max()}},\n\\item Position: \\code{\\link[dplyr:first]{first()}}, \\code{\\link[dplyr:last]{last()}}, \\code{\\link[dplyr:nth]{nth()}},\n\\item Count: \\code{\\link[dplyr:n]{n()}}, \\code{\\link[dplyr:n_distinct]{n_distinct()}}\n\\item Logical: \\code{\\link[=any]{any()}}, \\code{\\link[=all]{all()}}\n}\n\n}\n\n\\section{Backend variations}{\n\n\n\nThe data frame backend supports creating a variable and using it in the\nsame summary. This means that previously created summary variables can be\nfurther transformed or combined within the summary, as in \\code{\\link[dplyr:mutate]{mutate()}}.\nHowever, it also means that summary variables with the same names as previous\nvariables overwrite them, making those variables unavailable to later summary\nvariables.\n\nThis behaviour may not be supported in other backends. To avoid unexpected\nresults, consider using new names for your summary variables, especially when\ncreating multiple summaries.\n\n}\n\n\\section{Methods}{\n\n\nThis function is a \\strong{generic}, which means that packages can provide\nimplementations (methods) for other classes. See the documentation of\nindividual methods for extra arguments and differences in behaviour.\n\nThe following methods are currently available in loaded packages:\n\\Sexpr[stage=render,results=rd]{dplyr:::methods_rd(\"summarise\")}.\n\n}\n\n\\examples{\ndata(pbmc_small)\npbmc_small |> summarise(mean(nCount_RNA))\n\n}\n\\seealso{\nOther single table verbs: \n\\code{\\link{arrange}()},\n\\code{\\link{mutate}()},\n\\code{\\link{rename}()},\n\\code{\\link{slice}()}\n}\n\\concept{single table verbs}\n"
  },
  {
    "path": "man/tbl_format_header.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/print_method.R\n\\name{tbl_format_header}\n\\alias{tbl_format_header}\n\\alias{tbl_format_header.tidySeurat}\n\\title{Format the header of a tibble}\n\\usage{\n\\method{tbl_format_header}{tidySeurat}(x, setup, ...)\n}\n\\arguments{\n\\item{x}{A tibble-like object.}\n\n\\item{setup}{A setup object returned from \\code{\\link[pillar:tbl_format_setup]{tbl_format_setup()}}.}\n\n\\item{...}{These dots are for future extensions and must be empty.}\n}\n\\value{\nA character vector.\n}\n\\description{\n\\ifelse{html}{\\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\\strong{[Experimental]}}\n\nFor easier customization, the formatting of a tibble is split\ninto three components: header, body, and footer.\nThe \\code{tbl_format_header()} method is responsible for formatting the header\nof a tibble.\n\nOverride this method if you need to change the appearance\nof the entire header.\nIf you only need to change or extend the components shown in the header,\noverride or extend \\code{\\link[pillar:tbl_sum]{tbl_sum()}} for your class which is called by the\ndefault method.\n}\n\\examples{\n# TODO\n\n}\n"
  },
  {
    "path": "man/tidy.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/methods.R\n\\name{tidy}\n\\alias{tidy}\n\\alias{tidy.Seurat}\n\\title{tidy for Seurat objects}\n\\usage{\n\\method{tidy}{Seurat}(x, ...)\n}\n\\arguments{\n\\item{x}{A Seurat object}\n\n\\item{...}{Additional arguments (not used)}\n}\n\\value{\nA tidyseurat object\n}\n\\description{\ntidy for Seurat objects\n}\n"
  },
  {
    "path": "man/unite.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/tidyr_methods.R\n\\name{unite}\n\\alias{unite}\n\\alias{unite.Seurat}\n\\title{Unite multiple columns into one by pasting strings together}\n\\usage{\n\\method{unite}{Seurat}(data, col, ..., sep = \"_\", remove = TRUE, na.rm = FALSE)\n}\n\\arguments{\n\\item{data}{A data frame.}\n\n\\item{col}{The name of the new column, as a string or symbol.\n\nThis argument is passed by expression and supports\n\\link[rlang:topic-inject]{quasiquotation} (you can unquote strings\nand symbols). The name is captured from the expression with\n\\code{\\link[rlang:defusing-advanced]{rlang::ensym()}} (note that this kind of interface where\nsymbols do not represent actual objects is now discouraged in the\ntidyverse; we support it here for backward compatibility).}\n\n\\item{...}{<\\code{\\link[tidyr:tidyr_tidy_select]{tidy-select}}> Columns to unite}\n\n\\item{sep}{Separator to use between values.}\n\n\\item{remove}{If \\code{TRUE}, remove input columns from output data frame.}\n\n\\item{na.rm}{If \\code{TRUE}, missing values will be removed prior to uniting\neach value.}\n}\n\\value{\n`tidyseurat`\n}\n\\description{\nConvenience function to paste together multiple columns into one.\n}\n\\examples{\ndata(pbmc_small)\npbmc_small |> unite(\n  col=\"new_col\", \n  c(\"orig.ident\", \"groups\"))\n    \n}\n\\seealso{\n\\code{\\link[tidyr:separate]{separate()}}, the complement.\n}\n"
  },
  {
    "path": "man/unnest.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/tidyr_methods.R\n\\name{unnest}\n\\alias{unnest}\n\\alias{unnest.tidyseurat_nested}\n\\alias{unnest_seurat}\n\\title{Unnest a list-column of data frames into rows and columns}\n\\usage{\n\\method{unnest}{tidyseurat_nested}(\n  data,\n  cols,\n  ...,\n  keep_empty = FALSE,\n  ptype = NULL,\n  names_sep = NULL,\n  names_repair = \"check_unique\",\n  .drop,\n  .id,\n  .sep,\n  .preserve\n)\n\nunnest_seurat(\n  data,\n  cols,\n  ...,\n  keep_empty = FALSE,\n  ptype = NULL,\n  names_sep = NULL,\n  names_repair = \"check_unique\",\n  .drop,\n  .id,\n  .sep,\n  .preserve\n)\n}\n\\arguments{\n\\item{data}{A data frame.}\n\n\\item{cols}{<\\code{\\link[tidyr:tidyr_tidy_select]{tidy-select}}> List-columns to unnest.\n\nWhen selecting multiple columns, values from the same row will be recycled\nto their common size.}\n\n\\item{...}{\\ifelse{html}{\\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\\strong{[Deprecated]}}:\npreviously you could write \\code{df |> unnest(x, y, z)}.\nConvert to \\code{df |> unnest(c(x, y, z))}. If you previously created a new\nvariable in \\code{unnest()} you'll now need to do it explicitly with \\code{mutate()}.\nConvert \\code{df |> unnest(y = fun(x, y, z))}\nto \\code{df |> mutate(y = fun(x, y, z)) |> unnest(y)}.}\n\n\\item{keep_empty}{By default, you get one row of output for each element\nof the list that you are unchopping/unnesting. This means that if there's a\nsize-0 element (like \\code{NULL} or an empty data frame or vector), then that\nentire row will be dropped from the output. If you want to preserve all\nrows, use \\code{keep_empty = TRUE} to replace size-0 elements with a single row\nof missing values.}\n\n\\item{ptype}{Optionally, a named list of column name-prototype pairs to\ncoerce \\code{cols} to, overriding the default that will be guessed from\ncombining the individual values. Alternatively, a single empty ptype\ncan be supplied, which will be applied to all \\code{cols}.}\n\n\\item{names_sep}{If \\code{NULL}, the default, the outer names will come from the\ninner names. If a string, the outer names will be formed by pasting\ntogether the outer and the inner column names, separated by \\code{names_sep}.}\n\n\\item{names_repair}{Used to check that output data frame has valid\nnames. Must be one of the following options:\n\\itemize{\n\\item \\verb{\"minimal}\": no name repair or checks, beyond basic existence,\n\\item \\verb{\"unique}\": make sure names are unique and not empty,\n\\item \\verb{\"check_unique}\": (the default), no name repair, but check they are unique,\n\\item \\verb{\"universal}\": make the names unique and syntactic\n\\item a function: apply custom name repair.\n\\item \\link[tidyr]{tidyr_legacy}: use the name repair from tidyr 0.8.\n\\item a formula: a purrr-style anonymous function (see \\code{\\link[rlang:as_function]{rlang::as_function()}})\n}\n\nSee \\code{\\link[vctrs:vec_as_names]{vctrs::vec_as_names()}} for more details on these terms and the\nstrategies used to enforce them.}\n\n\\item{.drop, .preserve}{\\ifelse{html}{\\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\\strong{[Deprecated]}}:\nall list-columns are now preserved; If there are any that you\ndon't want in the output use \\code{select()} to remove them prior to\nunnesting.}\n\n\\item{.id}{\\ifelse{html}{\\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\\strong{[Deprecated]}}:\nconvert \\code{df |> unnest(x, .id = \"id\")} to \\verb{df |> mutate(id = names(x)) |> unnest(x))}.}\n\n\\item{.sep}{\\ifelse{html}{\\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\\strong{[Deprecated]}}:\nuse \\code{names_sep} instead.}\n}\n\\value{\n`tidyseurat`\n}\n\\description{\nUnnest expands a list-column containing data frames into rows and columns.\n}\n\\section{New syntax}{\n\n\ntidyr 1.0.0 introduced a new syntax for \\code{nest()} and \\code{unnest()} that's\ndesigned to be more similar to other functions. Converting to the new syntax\nshould be straightforward (guided by the message you'll receive) but if\nyou just need to run an old analysis, you can easily revert to the previous\nbehaviour using \\code{\\link[tidyr:nest_legacy]{nest_legacy()}} and \\code{\\link[tidyr:unnest_legacy]{unnest_legacy()}} as follows:\n\n\\if{html}{\\out{<div class=\"sourceCode\">}}\\preformatted{library(tidyr)\nnest <- nest_legacy\nunnest <- unnest_legacy\n}\\if{html}{\\out{</div>}}\n\n}\n\n\\examples{\ndata(pbmc_small)\npbmc_small |> \n    nest(data=-groups) |> \n    unnest(data)\n\n}\n\\seealso{\nOther rectangling: \n\\code{\\link[tidyr]{hoist}()},\n\\code{\\link[tidyr]{unnest_longer}()},\n\\code{\\link[tidyr]{unnest_wider}()}\n}\n"
  },
  {
    "path": "tests/testthat/test-dplyr.R",
    "content": "context('dplyr test')\n\nlibrary(Seurat)\ndata(\"pbmc_small\")\nset.seed(42)\n\ntest_that(\"arrange\", {\n  \n  pbmc_small |> \n    arrange(nFeature_RNA) |> \n    expect_warning(regexp = \"`arrange\\\\(\\\\)` was deprecated in tidyseurat .*\")\n  \n  # pbmc_small_pca_arranged <- pbmc_small |> arrange(nFeature_RNA) |> Seurat::ScaleData() |> Seurat::FindVariableFeatures() |> Seurat::RunPCA()\n  # pbmc_small_pca <- pbmc_small |> Seurat::ScaleData() |> Seurat::FindVariableFeatures() |> Seurat::RunPCA()\n  # expect_equal(\n  #   Seurat::VariableFeatures(pbmc_small_pca_arranged),\n  #   Seurat::VariableFeatures(pbmc_small_pca)\n  # )\n  \n  # # Failing only for ATLAS CRAN, but succeding for the rest\n  # expect_equal(\n  #   pbmc_small_pca_arranged[[\"pca\"]]@cell.embeddings,\n  #   pbmc_small_pca[[\"pca\"]]@cell.embeddings,\n  #   tolerance=0.1\n  # )\n  # expect_equal(\n  #   pbmc_small_pca_arranged |> as_tibble() |>dplyr::slice_head(n = 1),\n  #   pbmc_small_pca |> as_tibble() |> dplyr::slice_min(nFeature_RNA, n = 1)\n  # )\n\n})\n\ntest_that(\"bind_cols\", {\n  pbmc_small_bind <- pbmc_small |> select(nCount_RNA, nFeature_RNA)\n  pbmc_small |>\n    ttservice::bind_cols(pbmc_small_bind) |>\n    select(nCount_RNA...2, nFeature_RNA...3) |>\n    ncol() |>\n    expect_equal(2)\n})\n\ntest_that(\"distinct\", {\n  expect_equal(pbmc_small |> distinct(groups) |> ncol(), 1)\n})\n\ntest_that(\"filter\", {\n  expect_equal(\n    pbmc_small |> filter(groups == \"g1\") |> ncol(),\n    sum(pbmc_small[[]]$groups == \"g1\")\n  )\n})\n\ntest_that(\"group_by\", {\n  expect_equal(\n    pbmc_small |> group_by(groups) |> nrow(),\n    nrow(pbmc_small[[]])\n  )\n})\n\ntest_that(\"summarise\", {\n  expect_equal(pbmc_small |> summarise(mean(nCount_RNA)) |> nrow(), 1)\n})\n\ntest_that(\"mutate\", {\n  expect_equal(pbmc_small |> mutate(nFeature_RNA = 1) |> distinct(nFeature_RNA) |> nrow(), 1)\n})\n\ntest_that(\"rename\", {\n  expect_equal(pbmc_small |> rename(s_score = nFeature_RNA) |> select(s_score) |> ncol(), 1)\n})\n\ntest_that(\"left_join\", {\n  expect_equal(\n    pbmc_small |> left_join(pbmc_small |> distinct(groups) |> mutate(new_column = 1:2) |> slice(1)) |> ncol(),\n    nrow(pbmc_small[[]])\n  )\n})\n\ntest_that(\"inner_join\", {\n  expect_equal(\n    pbmc_small |> inner_join(pbmc_small |> distinct(groups) |> mutate(new_column = 1:2) |> slice(1)) |> ncol(),\n    sum(pbmc_small[[]]$groups == \"g2\")\n  )\n})\n\ntest_that(\"right_join\", {\n  expect_equal(\n    pbmc_small |> right_join(pbmc_small |> distinct(groups) |> mutate(new_column = 1:2) |> slice(1)) |> ncol(),\n    sum(pbmc_small[[]]$groups == \"g2\")\n  )\n})\n\ntest_that(\"full_join\", {\n  expect_equal(\n    pbmc_small |> full_join(tibble::tibble(groups = \"g1\", other = 1:4)) |> nrow(),\n    sum(pbmc_small[[]]$groups == \"g1\") * 4 + sum(pbmc_small[[]]$groups == \"g2\")\n  )\n})\n\ntest_that(\"slice\", {\n  expect_equal(pbmc_small |> slice(1) |> ncol(), 1)\n  expect_equal(\n    pbmc_small |> slice(1:6) |> colnames(),\n    colnames(pbmc_small) |> head(6))\n})\n\ntest_that(\"sample_n\", {\n  expect_equal(pbmc_small |> sample_n(50) |> ncol(), 50)\n  expect_equal(\n    pbmc_small |> sample_n(500, replace = TRUE) |> ncol(),\n    pbmc_small |> as_tibble() |> ncol()\n  )\n})\n\ntest_that(\"slice_sample\", {\n  pbmc_small |>\n    slice_sample(n = 50) |>\n    ncol() |>\n    expect_equal(50)\n})\n\ntest_that(\"slice_head\", {\n  pbmc_small |>\n    slice_head(n = 50) |>\n    ncol() |>\n    expect_equal(50)\n  expect_equal(\n    colnames(pbmc_small) |> head(n = 50),\n    pbmc_small |> slice_head(n = 50) |> colnames()\n  )\n})\n\ntest_that(\"slice_tail\", {\n  pbmc_small |>\n    slice_tail(n = 50) |>\n    ncol() |>\n    expect_equal(50)\n  expect_equal(\n    colnames(pbmc_small) |> tail(n = 50),\n    pbmc_small |> slice_tail(n = 50) |> colnames()\n  )\n})\n\ntest_that(\"slice_min\", {\n  pbmc_small |>\n    slice_min(nFeature_RNA, n = 5) |>\n    ncol() |>\n    expect_equal(5)\n  \n  # Arrange is deprecated\n  # expect_equal(\n  #   pbmc_small |> as_tibble() |> arrange(nFeature_RNA) |> head(n = 5) %>% pull(.cell),\n  #   pbmc_small |> slice_min(nFeature_RNA, n = 5) |> colnames()\n  # )\n})\n\ntest_that(\"slice_max\", {\n  pbmc_small |>\n    slice_max(nFeature_RNA, n = 5) |>\n    ncol() |>\n    expect_equal(5)\n  \n  # Arrange is deprecated\n  # expect_equal(\n  #   pbmc_small |> as_tibble() |> arrange(desc(nFeature_RNA)) |> head(n = 5) %>% pull(.cell),\n  #   pbmc_small |> slice_max(nFeature_RNA, n = 5) |> colnames()\n  # )\n})\n\ntest_that(\"slice_min slice_max tibble input for order_by\", {\n  pbmc_small |>\n    slice_min(tibble::tibble(nFeature_RNA, nCount_RNA), n = 5) |>\n    ncol() |>\n    expect_equal(5)\n  pbmc_small |>\n    slice_max(tibble::tibble(nFeature_RNA, nCount_RNA), n = 5) |>\n    ncol() |>\n    expect_equal(5)\n})\n\ntest_that(\"select\", {\n  expect_equal(pbmc_small |> select(cell, orig.ident) |> class() |> as.character(), \"Seurat\")\n  expect_equal(pbmc_small |> select(orig.ident) |> class() |> as.character() |> purrr::pluck(1), \"tbl_df\")\n})\n\ntest_that(\"sample_frac\", {\n  expect_equal(\n    pbmc_small |> sample_frac(0.1) |> ncol(),\n    nrow(pbmc_small[[]]) * 0.1\n  )\n  expect_equal(\n    pbmc_small |> sample_frac(10, replace = TRUE) |> ncol(),\n    pbmc_small |> as_tibble() |> ncol()\n  )\n})\n\ntest_that(\"count\", {\n  expect_equal(\n    pbmc_small |> count(groups) |> nrow(),\n    pbmc_small[[]]$groups |> unique() |> length()\n  )\n})\n\ntest_that(\"add_count\", {\n  expect_equal(\n    pbmc_small |> add_count(groups) |> nrow(),\n    pbmc_small |> rownames() |> length()\n  )\n})\n\ntest_that(\"rowwise\", {\n  expect_equal(\n    pbmc_small |> rowwise() |> mutate(m = mean(c(nCount_RNA, nFeature_RNA))) |> purrr::pluck(\"m\", 1),\n    ((pbmc_small[, 1]$nCount_RNA + pbmc_small[, 1]$nFeature_RNA) / 2) |> unname()\n  )\n})\n\ntest_that(\"group_split() works for one variable\", {\n  fd <- pbmc_small |> \n    group_split(groups)\n  expect_equal(length(fd), length(unique(pbmc_small$groups)))\n})\n\ntest_that(\"group_split() works for combination of variables\", {\n  fd <- pbmc_small |> \n    group_split(groups, letter.idents)\n  expect_equal(length(fd), length(unique(pbmc_small$groups)) *\n                 length(unique(pbmc_small$letter.idents)))\n})\n\ntest_that(\"group_split() works for one logical statement\", {\n  fd_log <- pbmc_small |> \n    group_split(groups==\"g1\")\n  fd_var <- pbmc_small |> \n    group_split(groups==\"g1\")\n  expect_equal(lapply(fd_var, count), lapply(fd_log, count))\n})\n\ntest_that(\"group_split() works for two logical statements\", {\n  fd <- pbmc_small |>\n    group_split(PC_1>0 & groups==\"g1\")\n  fd_counts <- lapply(fd, count)\n  expect_equal(c(fd_counts[[1]], fd_counts[[2]], use.names = FALSE), \n               list(75, 5))\n})\n"
  },
  {
    "path": "tests/testthat/test-ggplotly_methods.R",
    "content": "context('ggplot test')\n\ndata(\"pbmc_small\")\n\ndf <- pbmc_small\ndf$number <- rnorm(ncol(df))\ndf$factor <- sample(gl(3, 1, ncol(df)))\n\ntest_that(\"ggplot\", {\n  # cell metadata\n  p <- ggplot(df, aes(factor, number)) \n  expect_silent(show(p))\n  expect_s3_class(p, \"ggplot\")\n  # assay data\n  g <- sample(rownames(df), 1)\n  fd <- join_features(df, g, shape=\"wide\")\n  p <- ggplot(fd, aes(factor, .data[[g]]))\n  expect_silent(show(p))\n  expect_s3_class(p, \"ggplot\")\n  # reduced dimensions\n  p <- ggplot(df, aes(PC_1, PC_2, col=factor))\n  expect_silent(show(p))\n  expect_s3_class(p, \"ggplot\")\n})\n\ntest_that(\"plotly\", {\n  # cell metadata\n  p <- plot_ly(df, x=~factor, y=~number, type=\"violin\") \n  expect_silent(show(p))\n  expect_s3_class(p, \"plotly\")\n  # assay data\n  g <- sample(rownames(df), 1)\n  fd <- join_features(df, g, shape=\"wide\")\n  p <- plot_ly(fd, x=~factor, y=g, type=\"violin\") \n  expect_silent(show(p))\n  expect_s3_class(p, \"plotly\")\n  # reduced dimensions\n  p <- plot_ly(fd, x=~PC_1, y=~PC_2, type=\"scatter\", mode=\"markers\") \n  expect_silent(show(p))\n  expect_s3_class(p, \"plotly\")\n})\n"
  },
  {
    "path": "tests/testthat/test-methods.R",
    "content": "context('methods test')\n\ndata(\"pbmc_small\")\n\ntest_that(\"join_features_long\", {\n  pbmc_small |> \n    join_features(\"CD3D\", shape=\"long\") |> \n    slice(1) |>\n    pull(.abundance_RNA) |>\n    expect_equal(6.35, tolerance = 0.1)\n})\n\ntest_that(\"join_features_wide\", {\n  pbmc_small |> \n    join_features(\"CD3D\", shape=\"wide\") |> \n    slice(1) |>\n    pull(CD3D) |>\n    expect_equal(6.35, tolerance = 0.1)\n})\n\ntest_that(\"join_features_default_wide\", {\n  pbmc_small |> \n    join_features(\"CD3D\") |> \n    slice(1) |>\n    pull(CD3D) |>\n    expect_equal(6.35, tolerance = 0.1)\n})\n\ntest_that(\"aggregate_cells() returns expected values\", {\n  # Create pseudo-bulk object for testing\n  pbmc_pseudo_bulk <-\n    pbmc_small |>\n    aggregate_cells(c(groups, letter.idents), assays = \"RNA\")\n  \n  # Check row length is unchanged\n  pbmc_pseudo_bulk |>\n    distinct(.feature) |> \n    nrow() |>\n    expect_equal(pbmc_small |> nrow())\n  \n  # Check column length is correctly modified\n  pbmc_pseudo_bulk |> \n    distinct(.sample) |> \n    nrow() |>\n    expect_equal(pbmc_small |>\n                   as_tibble() |>\n                   select(groups, letter.idents) |>\n                   unique() |>\n                   nrow()\n    )\n  # Spot check for correctly aggregated count value of ACAP1 gene\n  pbmc_pseudo_bulk |> \n    filter(.feature == \"ACAP1\" & .sample == \"g1___A\") |> \n    select(RNA) |> \n    as.numeric() |> \n    expect_equal(\n      Seurat::DietSeurat(pbmc_small, assays = \"RNA\", features = \"ACAP1\")[, pbmc_small |>\n                                  as_tibble() |>\n                                  filter(groups == \"g1\", letter.idents == \"A\") |>\n                                  pull(.cell)] |>\n        LayerData() |> \n        sum())\n  \n  # Aggregate with tidyselect\n  pbmc_small |>\n    aggregate_cells(c(any_of(\"groups\"), letter.idents), assays = \"RNA\") |> \n    expect_no_error()\n})\n\ntest_that(\"get_abundance_sc_wide\", {\n  expect_equal(\n    pbmc_small |> get_abundance_sc_wide() |> nrow(),\n    pbmc_small[[]] |> nrow()\n  )\n  expect_equal(\n    pbmc_small |> get_abundance_sc_wide() |> pull(\"S100A9\") |> sum(),\n    pbmc_small |> FetchData(\"S100A9\") |> sum(), \n    tolerance = 0.1\n )\n})\n\ntest_that(\"get_abundance_sc_long\", {\n  expect_equal(pbmc_small |> get_abundance_sc_long() |> ncol(), 3)\n  expect_equal(\n    pbmc_small |> get_abundance_sc_long() |> filter(.feature == \"S100A9\") |> pull(\".abundance_RNA\") |> sum(),\n    pbmc_small |> FetchData(\"S100A9\") |> sum(),\n    tolerance = 0.1\n  )\n})\n\n\n\n"
  },
  {
    "path": "tests/testthat/test-pillar.R",
    "content": "context('pillar test')\n\ntest_string <- \"A small string to test the function of pillar utilities.\"\n\ntest_that(\"pillar___format_comment\", {\n  test_string |>\n    pillar___format_comment(width = 20) |>\n    stringr::str_count(\"# \") |> \n    expect_equal(5)\n})\n\ntest_that(\"pillar___strwrap2\", {\n  test_string |>\n    pillar___strwrap2(width = 20, indent = 4) |>\n    stringr::str_count(\"      \") |> \n    expect_equal(c(0, 1, 1, 1, 1))\n})\n\ntest_that(\"pillar___wrap\", {\n  test_string |>\n    pillar___wrap(width = 20) |>\n    stringr::str_count(\"\\n\") |> \n    expect_equal(3)\n})"
  },
  {
    "path": "tests/testthat/test-print.R",
    "content": "context('print test')\n\ndata(\"pbmc_small\")\n\ntest_that(\"print\", {\n  text <- capture.output(print(pbmc_small))\n  expect_equal(grep(\"Seurat-tibble abstraction\", text), 1)\n  i <- grep(str <- \".*Features=([0-9]+).*\", text)\n  expect_equal(gsub(str, \"\\\\1\", text[i]), paste(nrow(pbmc_small)))\n  i <- grep(str <- \".*Cells=([0-9]+).*\", text)\n  expect_equal(gsub(str, \"\\\\1\", text[i]), paste(ncol(pbmc_small)))\n})\n\ntest_that(\"glimpse\", {\n  text <- capture.output(glimpse(pbmc_small))\n  expect_equal(length(text), 37)\n})\n"
  },
  {
    "path": "tests/testthat/test-tidyr.R",
    "content": "context('tidyr test')\n\ndata(\"pbmc_small\")\ntt <- GetAssayData(pbmc_small, layer = 'counts', assay = \"RNA\") |> CreateSeuratObject() |> mutate(groups = sprintf(\"g%s\", rep(1:2, dplyr::n()/2)))\n\ntest_that(\"nest_unnest\", {\n  col_names <- colnames(tt[[]]) |> c(\"cell\")\n  x <- tt |> nest(data = -groups) |> unnest(data) |> Seurat::NormalizeData() |>  Seurat::ScaleData() |> Seurat::FindVariableFeatures() |> Seurat::RunPCA()\n  y <- tt |> Seurat::NormalizeData() |> Seurat::ScaleData() |> Seurat::FindVariableFeatures() |> Seurat::RunPCA()\n  expect_equal(\n    x[[\"pca\"]]@cell.embeddings |> as_tibble(rownames = \"cell\") |> arrange(cell) |> pull(PC_1),\n    y[[\"pca\"]]@cell.embeddings |> as_tibble(rownames = \"cell\") |> arrange(cell) |> pull(PC_1)\n  )\n})\n\ntest_that(\"fast_vs_slow_nest\", {\n  expect_identical(\n    tt |> mutate(groups2 = groups) |> nest(data = -c(groups, groups2)) |> select(-groups2),\n    tt |> nest(data = -groups) \n  )\n})\n\ntest_that(\"nest_unnest_slice_1\", {\n  expect_equal(\n    tt |> nest(data = -groups) |> slice(1) |> unnest(data) |> ncol(),\n    sum(tt[[]]$groups == \"g1\")\n  )\n})\ntest_that(\"unite separate\", {\n  un <- tt |> unite(\"new_col\", c(orig.ident, groups))\n  se <- un |> separate(col = new_col, into = c(\"orig.ident\", \"groups\"))\n  expect_equal(un |> select(new_col) |> slice(1) |> pull(new_col), \"SeuratProject_g1\")\n  expect_equal(se |> select(orig.ident) |> ncol(), 1)\n})\n\ntest_that(\"extract\", {\n  expect_equal(\n    tt |> extract(groups, into = \"g\", regex = \"g([0-9])\", convert = TRUE) |> pull(g) |> class(),\n    \"integer\"\n  )\n})\n\ntest_that(\"pivot_longer\", {\n  expect_equal(\n    tt |> pivot_longer(c(orig.ident, groups), names_to = \"name\", values_to = \"value\")  |> class() |> magrittr::extract2(1),\n    \"tbl_df\"\n  )\n})\n"
  },
  {
    "path": "tests/testthat/test-utilities.R",
    "content": "context('utilities test')\n\ndata(\"pbmc_small\")\n\ntest_that(\"get_special_column_name_symbol\", {\n  expect_equal(get_special_column_name_symbol(\".cell\")$symbol, rlang::sym(\".cell\"))\n  expect_equal(get_special_column_name_symbol(\".cell\")$name, c(\".cell\"))\n})\n\ntest_that(\"ping_old_special_column_into_metadata\", {\n  ping_old_special_column_into_metadata(pbmc_small) |>\n    as_tibble() |>\n    colnames() |>\n    purrr::pluck(1) |>\n    expect_equal(\"cell\")\n})\n\n"
  },
  {
    "path": "tests/testthat.R",
    "content": "library(testthat)\nlibrary(tidyseurat)\n\ntest_check(\"tidyseurat\")\n"
  },
  {
    "path": "vignettes/figures_article.Rmd",
    "content": "---\ntitle: \"Code for producing the figures in the article\"\nauthor: \"Stefano Mangiola\"\ndate: \"`r Sys.Date()`\"\npackage: tidyseurat\noutput:\n  html_vignette:\n    toc_float: true\nvignette: >\n  %\\VignetteEngine{knitr::knitr}\n  %\\VignetteIndexEntry{Code for producing the figures in the article}\n  %\\usepackage[UTF-8]{inputenc}\n---\n\n<!-- badges: start -->\n[![Lifecycle:maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html)\n<!-- badges: end -->\n\n```{r include=FALSE}\n# Set path to plotly screenshot. We don't run the plotly code chunk as most servers do not have javascript libraries needed for interactive plotting\nscreenshot <- \"../man/figures/plotly.png\"\n\n# The chunk below uses Rmd in man/fragments to avoid duplication, as the content is shared with the vignette and README. As suggested here: https://www.garrickadenbuie.com/blog/dry-vignette-and-readme/\n\nvisual_cue <- \"../man/figures/logo_interaction-01.png\"\n\n```\n\n```{r eval=FALSE}\n# Article workflow\n\nlibrary(tidyverse)\nlibrary(Seurat)\nlibrary(SingleR)\nlibrary(plotly)\nlibrary(tidyHeatmap)\nlibrary(ggalluvial)\nlibrary(ggplot2)\nlibrary(tidyseurat)\noptions(future.globals.maxSize = 50068 * 1024^2)\n\n# Use colourblind-friendly colours\nfriendly_cols <- dittoSeq::dittoColors()\n\n# Set theme\ncustom_theme <-\n  list(\n    scale_fill_manual(values = friendly_cols),\n    scale_color_manual(values = friendly_cols),\n    theme_bw() +\n      theme(\n        panel.border = element_blank(),\n        axis.line = element_line(),\n        panel.grid.major = element_line(size = 0.2),\n        panel.grid.minor = element_line(size = 0.1),\n        text = element_text(size = 9),\n        legend.position = \"bottom\",\n        strip.background = element_blank(),\n        axis.title.x = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),\n        axis.title.y = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),\n        axis.text.x = element_text(angle = 30, hjust = 1, vjust = 1)\n      )\n  )\n\nPBMC_clean_scaled_UMAP_cluster_cell_type <- readRDS(\"dev/PBMC_clean_scaled_UMAP_cluster_cell_type.rds\")\n```\n\n```{r eval=FALSE}\np1 = \n  PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  pivot_longer(\n    c(mito.fraction, S.Score, G2M.Score), \n    names_to=\"property\", \n    values_to=\"Value\"\n  ) %>%\n  mutate(property =  factor(property, levels = c(\"mito.fraction\", \"G2M.Score\", \"S.Score\"))) %>%\n  ggplot(aes(sample, Value)) + \n  geom_boxplot(outlier.size = 0.5 ) + \n  facet_wrap(~property, scales = \"free_y\" ) +\n  custom_theme +\n  theme(aspect.ratio=1)\n```\n\n```{r eval=FALSE}\np2 = \n  PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  sample_n(20000) %>%\n  ggplot(aes(UMAP_1, UMAP_2, color=seurat_clusters)) +\n  geom_point(size=0.05, alpha=0.2) +\n  custom_theme +\n  theme(aspect.ratio=1)\n\nPBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  sample_n(20000) %>%\n  plot_ly(\n    x = ~`UMAP_1`,\n    y = ~`UMAP_2`,\n    z = ~`UMAP_3`,\n    color = ~seurat_clusters,\n    colors = friendly_cols[1:24],sizes = 50, size = 1\n  )\n\nmarkers = readRDS(\"dev/PBMC_marker_df.rds\")\n```\n\n```{r eval=FALSE}\np3 = \n  PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  arrange(first.labels) %>%\n  mutate(seurat_clusters = fct_inorder(seurat_clusters)) %>%\n  join_features(features=c(\"CD3D\", \"HLA-DRB1\")) %>%\n  ggplot(aes(y=seurat_clusters , x=.abundance_SCT, fill=first.labels)) +\n  geom_density_ridges(bandwidth = 0.2) +\n  facet_wrap(~ .feature, nrow = 2) +\n  coord_flip() +\n  custom_theme\n```\n\n```{r eval=FALSE}\n# Plot heatmap\np4 = \n  PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  sample_n(2000) %>%\n  DoHeatmap(\n    features = markers$gene,\n    group.colors = friendly_cols\n  )\n```\n\n```{r eval=FALSE}\np5 = \n  PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  sample_n(1000) %>%\n  join_features(features=markers$gene) %>%\n  mutate(seurat_clusters = as.integer(seurat_clusters)) %>%\n  filter(seurat_clusters<10) %>%\n  group_by(seurat_clusters) %>%\n  \n  # Plot heatmap\n  heatmap(\n    .row = .feature,\n    .column = .cell, \n    .value = .abundance_SCT, \n    palette_grouping = list(rep(\"black\",9)), \n    palette_value = circlize::colorRamp2(c(-1.5, 0, 1.5), c(\"purple\", \"black\", \"yellow\")),\n    \n    # ComplexHeatmap parameters\n    row_gap = unit(0.1, \"mm\"), column_gap = unit(0.1, \"mm\")\n  ) %>%\n    \n  # Add annotation\n  add_tile(sample, palette = friendly_cols[1:7]) %>%\n  add_point(PC_1) \n```\n\n```{r eval=FALSE}\np6 = \n  PBMC_clean_scaled_UMAP_cluster_cell_type %>%\n  unite(\"cluster_cell_type\", c(first.labels, seurat_clusters), remove=FALSE) %>%\n  pivot_longer(\n    c(seurat_clusters, first.labels_single),\n    names_to = \"classification\", values_to = \"value\"\n  ) %>%\n  \n  ggplot(aes(x = classification, stratum = value, alluvium = cell,\n           fill = first.labels, label = value)) +\n  scale_x_discrete(expand = c(1, 1)) +\n  geom_flow() +\n  geom_stratum(alpha = .5) +\n  # geom_text(stat = \"stratum\", size = 3) +\n  geom_text_repel(stat = \"stratum\", size = 3,\n             nudge_x      = 0.05,\n             direction    = \"y\",\n             angle        = 0,\n             vjust        = 0,\n             segment.size = 0.2\n         ) +\n  scale_fill_manual(values = friendly_cols) +\n  #guides(fill = FALSE) +\n  coord_flip() +\n  theme_bw() +\n  theme(\n    panel.border = element_blank(),\n    axis.line = element_line(),\n    panel.grid.major = element_line(size = 0.2),\n    panel.grid.minor = element_line(size = 0.1),\n    text = element_text(size = 9),\n    legend.position = \"bottom\",\n    strip.background = element_blank(),\n    axis.title.x = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),\n    axis.title.y = element_text(margin = margin(t = 10, r = 10, b = 10, l = 10)),\n    axis.text.x = element_text(angle = 30, hjust = 1, vjust = 1)\n  )\n```\n\n"
  },
  {
    "path": "vignettes/introduction.Rmd",
    "content": "---\ntitle: \"Overview of the tidyseurat package\"\nauthor: \"Stefano Mangiola\"\ndate: \"`r Sys.Date()`\"\npackage: tidyseurat\noutput:\n  html_vignette:\n    toc_float: true\nbibliography: tidyseurat.bib\nvignette: >\n  %\\VignetteEngine{knitr::knitr}\n  %\\VignetteIndexEntry{Overview of the tidyseurat package}\n  %\\usepackage[UTF-8]{inputenc}\n---\n\n<!-- badges: start -->\n[![Lifecycle:maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html)\n<!-- badges: end -->\n\n```{r include=FALSE}\n# Set path to plotly screenshot. We don't run the plotly code chunk as most servers do not have javascript libraries needed for interactive plotting\nscreenshot <- \"../man/figures/plotly.png\"\n\n# The chunk below uses Rmd in man/fragments to avoid duplication, as the content is shared with the vignette and README. As suggested here: https://www.garrickadenbuie.com/blog/dry-vignette-and-readme/\n\nvisual_cue <- \"../man/figures/logo_interaction-01.png\"\n\n```\n\n```{r child=\"../man/fragments/intro.Rmd\"}\n```\n\n# Session Info\n\n```{r}\nsessionInfo()\n```\n\n\n# References"
  },
  {
    "path": "vignettes/tidyseurat.bib",
    "content": "@article{butler2018integrating,\n  title={Integrating single-cell transcriptomic data across different conditions, technologies, and species},\n  author={Butler, Andrew and Hoffman, Paul and Smibert, Peter and Papalexi, Efthymia and Satija, Rahul},\n  journal={Nature biotechnology},\n  volume={36},\n  number={5},\n  pages={411--420},\n  year={2018},\n  publisher={Nature Publishing Group}\n}\n\n@article{stuart2019comprehensive,\n  title={Comprehensive integration of single-cell data},\n  author={Stuart, Tim and Butler, Andrew and Hoffman, Paul and Hafemeister, Christoph and Papalexi, Efthymia and Mauck III, William M and Hao, Yuhan and Stoeckius, Marlon and Smibert, Peter and Satija, Rahul},\n  journal={Cell},\n  volume={177},\n  number={7},\n  pages={1888--1902},\n  year={2019},\n  publisher={Elsevier}\n}\n\n@article{aran2019reference,\n  title={Reference-based analysis of lung single-cell sequencing reveals a transitional profibrotic macrophage},\n  author={Aran, Dvir and Looney, Agnieszka P and Liu, Leqian and Wu, Esther and Fong, Valerie and Hsu, Austin and Chak, Suzanna and Naikawadi, Ram P and Wolters, Paul J and Abate, Adam R and others},\n  journal={Nature immunology},\n  volume={20},\n  number={2},\n  pages={163--172},\n  year={2019},\n  publisher={Nature Publishing Group}\n}\n\n@article{cabello2020singlecellsignalr,\n  title={SingleCellSignalR: inference of intercellular networks from single-cell transcriptomics},\n  author={Cabello-Aguilar, Simon and Alame, M{\\'e}lissa and Kon-Sun-Tack, Fabien and Fau, Caroline and Lacroix, Matthieu and Colinge, Jacques},\n  journal={Nucleic acids research},\n  volume={48},\n  number={10},\n  pages={e55--e55},\n  year={2020},\n  publisher={Oxford University Press}\n}\n\n@article{wickham2019welcome,\n  title={Welcome to the Tidyverse},\n  author={Wickham, Hadley and Averick, Mara and Bryan, Jennifer and Chang, Winston and McGowan, Lucy D'Agostino and Fran{\\c{c}}ois, Romain and Grolemund, Garrett and Hayes, Alex and Henry, Lionel and Hester, Jim and others},\n  journal={Journal of Open Source Software},\n  volume={4},\n  number={43},\n  pages={1686},\n  year={2019}\n}\n"
  }
]