2
$\begingroup$

So, the WorldCloud function applied to a string generates a word cloud graphic in which each word is sized according to its multiplicity in the string. Is there a way by which we can convert that same result in the form of list where each word is listed from the highest multiplicity to lowest multiplicity?

WordCloud["All children, except one, grow up. They soon know that \
they will grow up, and the way Wendy knew was this. One day when she \
was two years old she was playing in a garden, and she plucked \
another flower and ran with it to her mother. I suppose she must have \
looked rather delightful, for Mrs. Darling put her hand to her heart \
and cried, \"Oh, why can't you remain like this for ever!\" This was \
all that passed between them on the subject, but henceforth Wendy \
knew that she must grow up. You always know after you are two. Two is \
the beginning of the end."]
(* output will be world cloud graphic here, which we want in the form of a list like below *)
(* {grow, Wendy, know, knew.........} *)
$\endgroup$
4
  • $\begingroup$ Don't you have a weighted list or a flat list before you create the WordCloud? $\endgroup$
    – lericr
    May 11, 2022 at 4:19
  • $\begingroup$ Are you asking how to sort a weighted list by weight? Or are you asking how to take a flat list and sort its elements by frequency? I.e. is "word clouds" just a red herring here? $\endgroup$
    – lericr
    May 11, 2022 at 4:20
  • $\begingroup$ how to take data like WikipediaData["example"] which is converted to word cloud by WordCloud[]. Instead, I want a list or table ordered by frequency and not the world cloud. $\endgroup$
    – grshvetal
    May 11, 2022 at 5:06
  • 1
    $\begingroup$ This question shows no research effort and no minimal example. Consequently, I am casting a close vote. $\endgroup$
    – Syed
    May 11, 2022 at 6:55

3 Answers 3

1
$\begingroup$

If you want the data from WordCloud, which strips common words from the input string, here's an internal hack to retrieve that data:

Quiet@TextWords[]; (* trigger autoload, if needed *)
Internal`InheritedBlock[{TextWords},
   Unprotect[TextWords];
   DownValues@TextWords = Prepend[
     DownValues@TextWords,
     HoldPattern[TextWords[str_String] /; ! TrueQ[$in]] :> 
      Block[{$in = True},
       Sow[TextWords[str], "TextWords"]]
     ];
   Protect[TextWords];
   Reap[
    cloud = WordCloud[
     "All children, except one, grow up. They soon know that they \
will grow up, and the way Wendy knew was this. One day when she was \
two years old she was playing in a garden, and she plucked another \
flower and ran with it to her mother. I suppose she must have looked \
rather delightful, for Mrs. Darling put her hand to her heart and \
cried, \"Oh, why can't you remain like this for ever!\" This was all \
that passed between them on the subject, but henceforth Wendy knew \
that she must grow up. You always know after you are two. Two is the \
beginning of the end."],
    "TextWords"]
   ] // MapThread[#1[#2] &,
    {{Show[#, ImageSize -> Medium] &, 
      Grid@*ReverseSortBy[{Last, First}]@*Tally@*Flatten},
     #}] & // Row

Note the word cloud just has the strings without the counts. You can get the FontSize from the word cloud, but I don't know how consistently it may be interpreted in terms of counts:

Cases[cloud, Style[word_String, fs_, ___] :> {word, fs}, Infinity] // 
  With[{min = Min@Cases[#, Scaled[x_] :> x, Infinity]},
   # /. _[_, Scaled[x_]] :> x/min] &
(*
  {{"grow", 7.},
   {"Wendy", 4.}, {"know", 4.}, {"knew", 4.},
   {"henceforth", 1.}, ..., {"Oh", 1.}}
*)
$\endgroup$
2
$\begingroup$

TextWords can be used to extract words from text:

TextWords[WikipediaData["example"]] // Short
(* {Example,may,refer,to,<134>>,Barcelona,with,distinctive,architecture} *)

Maybe you want just nouns, in which case TextCases is useful:

TextCases[WikipediaData["example"], "Noun"] // Short
(* {Example,gratia,example,example,<37>>,stories,sermons,suburb,architecture} *)

Once you have the words, you'll proably want to normalize them to avoid undercounting due to capitalization. I'll use ToLowerCase. Then you can use Counts or Tally:

Counts[ToLowerCase[TextWords[WikipediaData["example"]]]] // Short
(* <|example->9,may->2,refer->1,to->3,<<93>>,with->1,distinctive->1,architecture->1|> *)

Tally[ToLowerCase[TextWords[WikipediaData["example"]]]] // Short
(* {{example,9},{may,2},{refer,1},<<94>>,{with,1},{distinctive,1},{architecture,1}} *)

Then you'll want to sort. The Association can be sorted directly, the tallies will need to sort by Last:

Counts[ToLowerCase[TextWords[WikipediaData["example"]]]] // Sort
(* or *)
Tally[ToLowerCase[TextWords[WikipediaData["example"]]]] // SortBy[Last]

Now, if you want just the words, not the frequencies, you can extract them:

Counts[ToLowerCase[TextWords[WikipediaData["example"]]]] // Sort // Keys
(* or *)
SortBy[Tally[ToLowerCase[TextWords[WikipediaData["example"]]]], Last][[All, 1]]

At some point you may want to filter the words (e.g. nouns like I showed with TextCases), but I don't know what criteria you want, and I also don't know the criteria WordCloud uses, so I don't have anything to show.

$\endgroup$
2
  • $\begingroup$ Thanks. Because WordCloud already does processing for us, I was hoping that there was some way to just take that processed data and carry on from there. $\endgroup$
    – grshvetal
    May 12, 2022 at 6:10
  • $\begingroup$ @grshvetal I suppose one could also take the point of view that because TextWords already does the processing for us, one might hope to avoid WordCloud. However, there is a difference: WordCloud calls TextWords after deleting common words, and then processes the output of TextWords and returns only the graphics. $\endgroup$
    – Michael E2
    May 12, 2022 at 18:11
1
$\begingroup$

Instead, I want a list or table ordered by frequency and not the world cloud

text = WikipediaData["example"];
wct = WordCounts[text] // Sort

For a column-wise presentation:

Normal[wct] // Multicolumn[#, 5] &

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.