Q:

Creating a one hot table from a list of frequency counts in R

I want to create a table of values derived from two lists of information, but I want to only take elements from the first list that meet a condition defined in the second list.
I have two lists as data frames in R. DF_A is a list of document terms with total frequency counts. DF_B is a list of documents with frequencies for each word in the document.
Here is my R code so far, which gets me a long way towards my goal. 
library(dplyr)
library(tidytext)

docs = read.csv("~/text.csv")
# > docs
# DOCID                                                      TEXT
# 1  Doc1       blue blue blue blue rose rose hats hats hats hats
# 2  Doc2                                               rose hats
# 3  Doc3  tall tall tall tall tall tall tall tall tall tall tall 
# 4  Doc4                                               cups cups
# 5  Doc5                                                    tall 

my_unigrams <- unnest_tokens(docs, unigram, TEXT, token = "ngrams", n = 1)

DF_A <- my_unigrams %>%
  count(unigram, sort = TRUE)

DF_A
#> DF_A
# A tibble: 5 x 2
# unigram     n
# <chr> <int>
# 1    tall    12
# 2    hats     5
# 3    blue     4
# 4    rose     3
# 5    cups     2

DF_B <- my_unigrams %>%
  count(DOCID, unigram, sort = TRUE)

# > DF_B
# A tibble: 8 x 3
# DOCID unigram     n
# <fctr>   <chr> <int>
# 1   Doc3    tall    11
# 2   Doc1    blue     4
# 3   Doc1    hats     4
# 4   Doc1    rose     2
# 5   Doc4    cups     2
# 6   Doc2    hats     1
# 7   Doc2    rose     1
# 8   Doc5    tall     1

# My goal is a "one hot" table where each document ID is a row name, and the top three most frequent terms are columns (each cell should contain either 1 or 0; basically yes/no that term occurs in that document). I want a table like this:

one_hot_table <- table(DF_B$DOCID,DF_B$unigram)
one_hot_table

# one_hot_table
#     blue  cups hats rose tall
# Doc1    1    0    1    1    0
# Doc2    0    0    1    1    0
# Doc3    0    0    0    0    1
# Doc4    0    1    0    0    0
# Doc5    0    0    0    0    1

"one_hot_table" above is close to what I want, except I want a subset: just the words that are the most frequent ("tall", "blue", "hats"). 
What I'm hoping is that I can remove the columns I don't want automatically. In my real table, there are thousands of columns and the methods I've found to delete columns ask me to name the column. I don't want to do that for thousands of columns. Ideally I would like a method that takes the one_hot_table as input, looks up each column name in DF_A, and produces a new data frame with just the top three most frequent. Something like this:
new_one_hot_table <- function(one_hot_table, DF_A, 3)

Any help will be much appreciated.

A:

Well, if you don't mind modifying DF_B into a new datatable, an easy approach would be:
DF_C <- DF_B %>% 
  semi_join(DF_A %>% 
              head(3), by = "unigram")

new_one_hot_table <- table(DF_C$DOCID,DF_C$unigram)

If you are still wanting your function approach, this should work I think (arbitrarily called hot_tablr):
hot_tablr <- function(one_hot_table, DF_A, select = 3){

  # First get a vector of column names of interest
  top <- DF_A %>% 
    head(select) %>% 
    pull(unigram)

  # Now only select columns of interest
  new <- one_hot_table[, top]

  return(new)

}

Hopefully I'm understanding your question correctly.  Hopefully it's apparent, but I'm using the dplyr package as suggested.

