I want to know how can I access, extract, and reference values from a plotly figure in R.
Consider, for example, the Sankey diagram from plotly's own site of which there is an abbreviated version here:
library(plotly)
fig <- plot_ly(
type = "sankey",
node = list(
label = c("A1", "A2", "B1", "B2", "C1", "C2"),
color = c("blue", "blue", "blue", "blue", "blue", "blue"),
line = list()
),
link = list(
source = c(0,1,0,2,3,3),
target = c(2,3,3,4,4,5),
value = c(8,4,2,8,4,2)
)
)
fig
If I do View(fig) in Rstudio, a new tab opens titled . (I don't know why this instead of 'fig'). In this tab I can go to x > visdat > 'strig of letters and numbers that is a function?' > attrs > node > x (as shown bellow).
Here all the x coordinates for the Sankey nodes appear.
I want to access these values so I can use them somewhere else. How do I do this? If I click on the right side of the Rsutudio tab to copy the code to console I get:
environment(.[["x"]][["visdat"]][["484c3ec36899"]])[["attrs"]][["node"]][["x"]]
which obviously doesn't work as there is no object named ..
In this case I have tried fig$x$visdat$`484c3ec36899`() but I cant do fig$x$visdat$`484c3ec36899`()$attr, and I don't know what else to do.
So, how can I access any value from a plotly object? Any documentation referencing this topic would also be helpful.
Thanks.
You can find the documentation of the data structure of plotly in R here: https://plotly.com/r/figure-structure/
To check the data structure you can use str(fig):
List of 8
$ x :List of 6
..$ visdat :List of 1
.. ..$ a3b8795a4:function ()
..$ cur_data: chr "a3b8795a4"
..$ attrs :List of 1
.. ..$ a3b8795a4:List of 6
.. .. ..$ node :List of 3
.. .. .. ..$ label: chr [1:6] "A1" "A2" "B1" "B2" ...
.. .. .. ..$ color: chr [1:6] "blue" "blue" "blue" "blue" ...
.. .. .. ..$ line : list()
.. .. ..$ link :List of 3
.. .. .. ..$ source: num [1:6] 0 1 0 2 3 3
.. .. .. ..$ target: num [1:6] 2 3 3 4 4 5
.. .. .. ..$ value : num [1:6] 8 4 2 8 4 2
.. .. ..$ alpha_stroke: num 1
.. .. ..$ sizes : num [1:2] 10 100
.. .. ..$ spans : num [1:2] 1 20
.. .. ..$ type : chr "sankey"
..$ layout :List of 3
.. ..$ width : NULL
.. ..$ height: NULL
.. ..$ margin:List of 4
.. .. ..$ b: num 40
.. .. ..$ l: num 60
.. .. ..$ t: num 25
.. .. ..$ r: num 10
..$ source : chr "A"
..$ config :List of 1
.. ..$ showSendToCloud: logi FALSE
..- attr(*, "TOJSON_FUNC")=function (x, ...)
$ width : NULL
$ height : NULL
$ sizingPolicy :List of 6
..$ defaultWidth : chr "100%"
..$ defaultHeight: num 400
..$ padding : NULL
..$ viewer :List of 6
.. ..$ defaultWidth : NULL
.. ..$ defaultHeight: NULL
.. ..$ padding : NULL
.. ..$ fill : logi TRUE
.. ..$ suppress : logi FALSE
.. ..$ paneHeight : NULL
..$ browser :List of 5
.. ..$ defaultWidth : NULL
.. ..$ defaultHeight: NULL
.. ..$ padding : NULL
.. ..$ fill : logi TRUE
.. ..$ external : logi FALSE
..$ knitr :List of 3
.. ..$ defaultWidth : NULL
.. ..$ defaultHeight: NULL
.. ..$ figure : logi TRUE
$ dependencies :List of 5
..$ :List of 10
.. ..$ name : chr "typedarray"
.. ..$ version : chr "0.1"
.. ..$ src :List of 1
.. .. ..$ file: chr "htmlwidgets/lib/typedarray"
.. ..$ meta : NULL
.. ..$ script : chr "typedarray.min.js"
.. ..$ stylesheet: NULL
.. ..$ head : NULL
.. ..$ attachment: NULL
.. ..$ package : chr "plotly"
.. ..$ all_files : logi FALSE
.. ..- attr(*, "class")= chr "html_dependency"
..$ :List of 10
.. ..$ name : chr "jquery"
.. ..$ version : chr "1.11.3"
.. ..$ src :List of 1
.. .. ..$ file: chr "lib/jquery"
.. ..$ meta : NULL
.. ..$ script : chr "jquery.min.js"
.. ..$ stylesheet: NULL
.. ..$ head : NULL
.. ..$ attachment: NULL
.. ..$ package : chr "crosstalk"
.. ..$ all_files : logi TRUE
.. ..- attr(*, "class")= chr "html_dependency"
..$ :List of 10
.. ..$ name : chr "crosstalk"
.. ..$ version : chr "1.1.0.1"
.. ..$ src :List of 1
.. .. ..$ file: chr "www"
.. ..$ meta : NULL
.. ..$ script : chr "js/crosstalk.min.js"
.. ..$ stylesheet: chr "css/crosstalk.css"
.. ..$ head : NULL
.. ..$ attachment: NULL
.. ..$ package : chr "crosstalk"
.. ..$ all_files : logi TRUE
.. ..- attr(*, "class")= chr "html_dependency"
..$ :List of 10
.. ..$ name : chr "plotly-htmlwidgets-css"
.. ..$ version : chr "1.52.2"
.. ..$ src :List of 1
.. .. ..$ file: chr "htmlwidgets/lib/plotlyjs"
.. ..$ meta : NULL
.. ..$ script : NULL
.. ..$ stylesheet: chr "plotly-htmlwidgets.css"
.. ..$ head : NULL
.. ..$ attachment: NULL
.. ..$ package : chr "plotly"
.. ..$ all_files : logi FALSE
.. ..- attr(*, "class")= chr "html_dependency"
..$ :List of 10
.. ..$ name : chr "plotly-main"
.. ..$ version : chr "1.52.2"
.. ..$ src :List of 1
.. .. ..$ file: chr "htmlwidgets/lib/plotlyjs"
.. ..$ meta : NULL
.. ..$ script : chr "plotly-latest.min.js"
.. ..$ stylesheet: NULL
.. ..$ head : NULL
.. ..$ attachment: NULL
.. ..$ package : chr "plotly"
.. ..$ all_files : logi FALSE
.. ..- attr(*, "class")= chr "html_dependency"
$ elementId : NULL
$ preRenderHook:function (p, registerFrames = TRUE)
$ jsHooks : list()
- attr(*, "class")= chr [1:2] "plotly" "htmlwidget"
- attr(*, "package")= chr "plotly"
You could extract the coordinates with:
unlist(fig$x$attrs)
Related
Differently from my collegue, after I load the tweets with R and I try to see the structure with str() the data appears in a messy way with a lot of dots, rather than being organized as a table, which is what happens with my collegue's computer, even if the codes are the same. I can't understand what is the problem, we have the same packages installed and the same R version.
library(rtweet)
library(ggplot2)
library(dplyr)
library(tibble)
library(tidytext)
library(stringr)
library(stringi)
library(igraph)
library(ggraph)
library(readr)
library(lubridate)
library(zoo)
appname <- ""
key <- ""
secret <- ""
twitter_token <- create_token( app = "", consumer_key = "", consumer_secret = "", access_token = "", access_secret = "")
tweets <- search_tweets(q = "#water + #climatechange", n = 10000, lang = "en", include_rts = FALSE)
str(tweets)
.. ..$ media :'data.frame': 1 obs. of 11 variables:
.. .. ..$ id : num 1.57e+18
.. .. ..$ id_str : chr "1573815153484759040"
.. .. ..$ indices :List of 1
.. .. .. ..$ :'data.frame': 1 obs. of 2 variables:
.. .. .. .. ..$ start: int 241
.. .. .. .. ..$ end : int 264
.. .. .. ..- attr(*, "class")= chr "AsIs"
.. .. ..$ media_url : chr "http://pbs.twimg.com/media/FddQiy2WAAAl59Q.jpg"
.. .. ..$ media_url_https: chr "https://pbs.twimg.com/media/FddQiy2WAAAl59Q.jpg"
.. .. ..$ url : chr "https
.. .. ..$ display_url : chr "pic.twitter.com/iFJTkF1S9S"
.. .. ..$ expanded_url : chr "https://twitter.com/TreeBanker/status/1573815156768968706/photo/1"
.. .. ..$ type : chr "photo"
.. .. ..$ sizes :List of 1
.. .. .. ..$ :'data.frame': 4 obs. of 4 variables:
.. .. .. .. ..$ w : int [1:4] 1096 680 150 1096
.. .. .. .. ..$ h : int [1:4] 733 455 150 733
.. .. .. .. ..$ resize: chr [1:4] "fit" "fit" "crop" "fit"
.. .. .. .. ..$ type : chr [1:4] "large" "small" "thumb" "medium"
.. .. ..$ ext_alt_text : logi NA
..$ :List of 5
.. ..$ media :'data.frame': 1 obs. of 11 variables:
.. .. ..$ id : num 1.57e+18
.. .. ..$ id_str : chr "1573815153484759040"
.. .. ..$ indices :List of 1
.. .. .. ..$ :'data.frame': 1 obs. of 2 variables:
I have an S4 object named 'res' which I got while using an R package called RDAVIDWebService. I can't seem to find a way to convert this object into a dataframe in R.
I tried using the function 'as.data.frame(res)' but it throws this error:
> as.data.frame(res)
Error in as.data.frame.default(res) :
cannot coerce class ‘structure("DAVIDFunctionalAnnotationTable", package = "RDAVIDWebService")’ to a data.frame
The structure of the object looks like this:
> str(res)
Formal class 'DAVIDFunctionalAnnotationTable' [package "RDAVIDWebService"] with 4 slots
..# Genes :'data.frame': 3011 obs. of 3 variables:
Formal class 'DAVIDGenes' [package "RDAVIDWebService"] with 5 slots
.. .. ..# .Data :List of 3
.. .. .. ..$ : chr [1:3011] "22574630" "3544383" "3544385" "3544382" ...
.. .. .. ..$ : chr [1:3011] "1,2-Dihydroxy-3-keto-5-methylthiopentene dioxygenase,
putative(LPMP_204190)" "10 kDa heat shock protein(Tc00.1047053508209.100)" "10 kDa heat shock
protein(Tc00.1047053508209.120)" "10 kDa heat shock protein(Tc00.1047053508209.90)" ...
.. .. .. ..$ : Factor w/ 11 levels "Leishmania braziliensis MHOM/BR/75/M2904",..: 6 10 10 10
10 10 10 2 6 6 ...
.. .. ..# names : chr [1:3] "ID" "Name" "Species"
.. .. ..# row.names: chr [1:3011] "1" "2" "3" "4" ...
.. .. ..# .S3Class : chr "data.frame"
.. .. ..# type : chr "Gene List Report"
..# Dictionary:List of 10
.. ..$ COG_ONTOLOGY :'data.frame': 18 obs. of 2 variables:
.. .. ..$ ID : chr [1:18] "Translation, ribosomal structure and biogenesis" "Lipid
metabolism" "Cell division and chromosome partitioning" "General function prediction only" ...
.. .. ..$ Term: chr [1:18] "" "" "" "" ...
.. ..$ GOTERM_BP_DIRECT:'data.frame': 215 obs. of 2 variables:
.. .. ..$ ID : chr [1:215] "GO:0006457" "GO:0051603" "GO:0008152" "GO:0006412" ...
.. .. ..$ Term: chr [1:215] "protein folding" "proteolysis involved in cellular protein
catabolic process" "metabolic process" "translation" ...
.. ..$ GOTERM_CC_DIRECT:'data.frame': 84 obs. of 2 variables:
.. .. ..$ ID : chr [1:84] "GO:0005737" "GO:0016021" "GO:0005634" "GO:0005839" ...
.. .. ..$ Term: chr [1:84] "cytoplasm" "integral component of membrane" "nucleus" "proteasome
core complex" ...
.. ..$ GOTERM_MF_DIRECT:'data.frame': 222 obs. of 2 variables:
.. .. ..$ ID : chr [1:222] "GO:0010309" "GO:0018580" "GO:0051213" "GO:0004298" ...
.. .. ..$ Term: chr [1:222] "acireductone dioxygenase [iron(II)-requiring] activity"
"nitronate monooxygenase activity" "dioxygenase activity" "threonine-type endopeptidase
activity" ...
.. ..$ INTERPRO :'data.frame': 695 obs. of 2 variables:
.. .. ..$ ID : chr [1:695] "IPR004313" "IPR011051" "IPR014710" "IPR011032" ...
.. .. ..$ Term: chr [1:695] "Acireductone dioxygenase ARD family" "RmlC-like cupin domain"
"RmlC-like jelly roll fold" "GroES-like" ...
.. ..$ KEGG_PATHWAY :'data.frame': 363 obs. of 2 variables:
.. .. ..$ ID : chr [1:363] "ldo00071" "ldo00280" "ldo01100" "lmi00280" ...
.. .. ..$ Term: chr [1:363] "Fatty acid degradation" "Valine, leucine and isoleucine
degradation" "Metabolic pathways" "Valine, leucine and isoleucine degradation" ...
.. ..$ PIR_SUPERFAMILY :'data.frame': 44 obs. of 2 variables:
.. .. ..$ ID : chr [1:44] "PIRSF000868" "PIRSF002144" "PIRSF002134" "PIRSF002122" ...
.. .. ..$ Term: chr [1:44] "14-3-3 protein" "ribosomal protein, S19p/S19a/S15e/organellar S19
types" "ribosomal protein, S13p/S13a/S18e/organellar S13 types" "ribosomal protein,
S7p/S7a/S5e/organellar S7 types" ...
.. ..$ SMART :'data.frame': 90 obs. of 2 variables:
.. .. ..$ ID : chr [1:90] "SM00883" "SM00101" "SM01386" "SM01387" ...
.. .. ..$ Term: chr [1:90] "SM00883" "14_3_3" "SM01386" "SM01387" ...
.. ..$ UP_KEYWORDS :'data.frame': 116 obs. of 2 variables:
.. .. ..$ ID : chr [1:116] "Coiled coil" "Complete proteome" "Dioxygenase" "Oxidoreductase"
...
.. .. ..$ Term: chr [1:116] "" "" "" "" ...
.. ..$ UP_SEQ_FEATURE :'data.frame': 13 obs. of 2 variables:
.. .. ..$ ID : chr [1:13] "chain:60S ribosomal protein L18" "chain:Probable eukaryotic
initiation factor 4A" "domain:Helicase ATP-binding" "domain:Helicase C-terminal" ...
.. .. ..$ Term: chr [1:13] "" "" "" "" ...
..# Membership:List of 10
.. ..$ COG_ONTOLOGY : logi [1:3011, 1:18] FALSE FALSE FALSE FALSE FALSE FALSE ...
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : NULL
.. .. .. ..$ : chr [1:18] "Translation, ribosomal structure and biogenesis" "Lipid metabolism"
"Cell division and chromosome partitioning" "General function prediction only" ...
.. ..$ GOTERM_BP_DIRECT: logi [1:3011, 1:215] FALSE TRUE TRUE TRUE TRUE TRUE ...
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : NULL
.. .. .. ..$ : chr [1:215] "GO:0006457" "GO:0051603" "GO:0008152" "GO:0006412" ...
.. ..$ GOTERM_CC_DIRECT: logi [1:3011, 1:84] FALSE TRUE TRUE TRUE TRUE TRUE ...
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : NULL
.. .. .. ..$ : chr [1:84] "GO:0005737" "GO:0016021" "GO:0005634" "GO:0005839" ...
.. ..$ GOTERM_MF_DIRECT: logi [1:3011, 1:222] TRUE FALSE FALSE FALSE FALSE FALSE ...
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : NULL
.. .. .. ..$ : chr [1:222] "GO:0010309" "GO:0018580" "GO:0051213" "GO:0004298" ...
.. ..$ INTERPRO : logi [1:3011, 1:695] TRUE FALSE FALSE FALSE FALSE FALSE ...
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : NULL
.. .. .. ..$ : chr [1:695] "IPR004313" "IPR011051" "IPR014710" "IPR011032" ...
.. ..$ KEGG_PATHWAY : logi [1:3011, 1:363] FALSE FALSE FALSE FALSE FALSE FALSE ...
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : NULL
.. .. .. ..$ : chr [1:363] "ldo00071" "ldo00280" "ldo01100" "lmi00280" ...
.. ..$ PIR_SUPERFAMILY : logi [1:3011, 1:44] FALSE FALSE FALSE FALSE FALSE FALSE ...
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : NULL
.. .. .. ..$ : chr [1:44] "PIRSF000868" "PIRSF002144" "PIRSF002134" "PIRSF002122" ...
.. ..$ SMART : logi [1:3011, 1:90] FALSE TRUE TRUE TRUE TRUE TRUE ...
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : NULL
.. .. .. ..$ : chr [1:90] "SM00883" "SM00101" "SM01386" "SM01387" ...
.. ..$ UP_KEYWORDS : logi [1:3011, 1:116] TRUE FALSE FALSE FALSE FALSE FALSE ...
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : NULL
.. .. .. ..$ : chr [1:116] "Coiled coil" "Complete proteome" "Dioxygenase" "Oxidoreductase"
...
.. ..$ UP_SEQ_FEATURE : logi [1:3011, 1:13] FALSE FALSE FALSE FALSE FALSE FALSE ...
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : NULL
.. .. .. ..$ : chr [1:13] "chain:60S ribosomal protein L18" "chain:Probable eukaryotic
initiation factor 4A" "domain:Helicase ATP-binding" "domain:Helicase C-terminal" ...
..# type : chr "Functional Annotation Table"
Also, is there a generalized way of converting any S4 object into a dataframe without caring about the data inside the object? This is important because the S4 objects I'm fetching with this R package could have varying number of lists/variables/characters inside each of the 4 slots(i.e. #Genes, #Dictionary, #Membership and #type).
Maybe the following functions can be of help.
as.data.frame.DAVIDFunctionalAnnotationTable <- function(x){
Genes <- x#Genes
y <- Genes#.Data
names(y) <- Genes#names
y
}
extractS4_Dictionary <- function(x) x#Dictionary
extractS4_Membership <- function(x) x#Membership
extractS4_type <- function(x) x#type
The call
as.data.frame(res)
will coerce res to a data.frame.
The other functions will extract the S4 object's members.
The following function will extract the membership for each annotation.
membership <- function(x, which){
y <- as.data.frame(x)
memb <- extractS4_Membership(x)
i <- memb[, which]
y[i, , drop = FALSE]
}
# example usage
membership(res, "COG_ONTOLOGY")
I have been trying to get the data from this link to be usable
url <- "https://www.sec.gov/Archives/edgar/data/1061165/0001567619-21-010580.txt"
that should be the same information as the one on this link
https://www.sec.gov/Archives/edgar/data/1061165/000156761921010580/xslForm13F_X01/form13fInfoTable.xml
I have been able to download the file into a .txt, but can not get the data
Thanks
The file appears to be two nested XML files. We can extract each of the components into lists with this code:
txt <- readLines("https://www.sec.gov/Archives/edgar/data/1061165/0001567619-21-010580.txt")
grep("</?XML>", txt)
# [1] 46 101 109 719
txt[grep("</?XML>", txt)]
# [1] "<XML>" "</XML>" "<XML>" "</XML>"
A brief inspection of the file informed that grep, suggesting that an XML file started and stopped, and then another started/stopped. If we stay within that, we can extract most of the data with
library(xml2)
first <- as_list(read_xml(paste(txt[47:100], collapse = "")))
str(first)
# List of 1
# $ edgarSubmission:List of 2
# ..$ headerData:List of 2
# .. ..$ submissionType:List of 1
# .. .. ..$ : chr "13F-HR"
# .. ..$ filerInfo :List of 4
# .. .. ..$ liveTestFlag :List of 1
# .. .. .. ..$ : chr "LIVE"
# .. .. ..$ flags :List of 3
# .. .. .. ..$ confirmingCopyFlag :List of 1
# .. .. .. .. ..$ : chr "false"
# .. .. .. ..$ returnCopyFlag :List of 1
# .. .. .. .. ..$ : chr "true"
# .. .. .. ..$ overrideInternetFlag:List of 1
# .. .. .. .. ..$ : chr "false"
# .. .. ..$ filer :List of 1
# .. .. .. ..$ credentials:List of 2
# .. .. .. .. ..$ cik:List of 1
# .. .. .. .. .. ..$ : chr "0001061165"
# .. .. .. .. ..$ ccc:List of 1
# .. .. .. .. .. ..$ : chr "XXXXXXXX"
# .. .. ..$ periodOfReport:List of 1
# .. .. .. ..$ : chr "03-31-2021"
# ..$ formData :List of 3
and the second batch:
second <- as_list(read_xml(paste(txt[110:718], collapse = "")))
str(second)
# List of 1
# $ informationTable:List of 38
# ..$ infoTable:List of 7
# .. ..$ nameOfIssuer :List of 1
# .. .. ..$ : chr "ADOBE SYSTEMS INCORPORATED"
# .. ..$ titleOfClass :List of 1
# .. .. ..$ : chr "COM"
# .. ..$ cusip :List of 1
# .. .. ..$ : chr "00724F101"
# .. ..$ value :List of 1
# .. .. ..$ : chr "1246613"
# .. ..$ shrsOrPrnAmt :List of 2
# .. .. ..$ sshPrnamt :List of 1
# .. .. .. ..$ : chr "2622406"
# .. .. ..$ sshPrnamtType:List of 1
# .. .. .. ..$ : chr "SH"
# .. ..$ investmentDiscretion:List of 1
# .. .. ..$ : chr "SOLE"
# .. ..$ votingAuthority :List of 3
# .. .. ..$ Sole :List of 1
# .. .. .. ..$ : chr "2622406"
# .. .. ..$ Shared:List of 1
# .. .. .. ..$ : chr "0"
# .. .. ..$ None :List of 1
# .. .. .. ..$ : chr "0"
# ..$ infoTable:List of 7
I'm not certain offhand how to extract the front-matter, I hope this is a good enough start.
I am trying to subset thead/tbody without directly calling rowlist$td$list$item$table$thead or rowlist[[td]][[list]][[item]][[table]][[thead]]. This
unlist(rowlist, use.names=FALSE )[ grepl( "tbody", names(unlist(rowlist)))] serves my purpose except I need it as multiple rows (e.g. two tr's in tbody)(i can split it but seems counter intuitive .
I know there should be a better way to work with HTML/XML but this is got I got for now.
str(rowlist)
List of 1
$ td:List of 1
..$ list:List of 1
.. ..$ item:List of 1
.. .. ..$ table:List of 2
.. .. .. ..$ thead:List of 1
.. .. .. .. ..$ tr:List of 7
.. .. .. .. .. ..$ th:List of 1
.. .. .. .. .. .. ..$ : chr "Test"
.. .. .. .. .. ..$ th:List of 1
.. .. .. .. .. .. ..$ : chr "Outcome"
.. .. .. .. .. ..$ th:List of 1
.. .. .. .. .. .. ..$ : chr "Subset"
.. .. .. .. .. ..$ th:List of 1
.. .. .. .. .. .. ..$ : chr "Cups"
.. .. .. .. .. ..$ th:List of 1
.. .. .. .. .. .. ..$ : chr "Bowls"
.. .. .. .. .. ..$ th:List of 1
.. .. .. .. .. .. ..$ : chr "Plates"
.. .. .. .. .. ..$ th:List of 1
.. .. .. .. .. .. ..$ : chr "Jars"
.. .. .. ..$ tbody:List of 2
.. .. .. .. ..$ tr:List of 7
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "test1"
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "High"
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "Low"
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "Gold"
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "Blue"
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "Green"
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "red"
.. .. .. .. .. ..- attr(*, "ID")= chr "id_511"
.. .. .. .. ..$ tr:List of 7
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "test2"
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "Low"
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "High"
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "Pink"
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "Blue"
.. .. .. .. .. ..$ td:List of 1
.. .. .. .. .. .. ..$ : chr "Purple"
.. .. .. .. .. ..$ td: list()
.. .. .. .. .. ..- attr(*, "ID")= chr "id_512"
.. ..- attr(*, "styleCode")= chr "none"
List looks like this
rowlist<-list(td = structure(list(list = structure(list(item = list(table = list(
thead = list(tr = list(
th = list("Test"), th = list("Outcome"), th = list("Set"), th = list("Cups"), th = list("Bowls"), th = list( "Plates"), th = list("Jars"))),
tbody = list(tr = structure(
list(td = list("test1"), td = list("High"), td = list("Low"), td = list("Gold"), td = list("Blue"), td = list("Green"), td = list("Red")), ID = "id_511"),
tr = structure(
list(td = list("test2"), td = list("Low"), td = list("High"), td = list("Pink"), td = list("Blue"), td = list("Purple"), td = list()), ID = "id_512"))))), styleCode = "none")), colspan = "20"))
If the object has to be handled as a nested list, one approach is to use rrapply in the rrapply-package (extension of base rapply):
library(rrapply) ## v1.2.1
out <- rrapply(rowlist,
classes = "list",
condition = function(x, .xname) .xname %in% c("thead", "tbody"),
how = "flatten")
str(out, list.len = 2)
#> List of 2
#> $ thead:List of 1
#> ..$ tr:List of 7
#> .. ..$ th:List of 1
#> .. .. ..$ : chr "Test"
#> .. ..$ th:List of 1
#> .. .. ..$ : chr "Outcome"
#> .. .. [list output truncated]
#> $ tbody:List of 2
#> ..$ tr:List of 7
#> .. ..$ td:List of 1
#> .. .. ..$ : chr "test1"
#> .. ..$ td:List of 1
#> .. .. ..$ : chr "High"
#> .. .. [list output truncated]
#> .. ..- attr(*, "ID")= chr "id_511"
#> ..$ tr:List of 7
#> .. ..$ td:List of 1
#> .. .. ..$ : chr "test2"
#> .. ..$ td:List of 1
#> .. .. ..$ : chr "Low"
#> .. .. [list output truncated]
#> .. ..- attr(*, "ID")= chr "id_512"
Here, the condition function returns only nodes with names thead or tbody, how = "flatten" returns the nodes in a flat list (how = "prune" would prune the nodes keeping the original list structure), and classes = "list" does not skip intermediate list nodes (as would be the case with base rapply()).
I would like to login to a webpage with a pop up sign in window. This article logs into Stack Overflow, a webpage that has a visible login form. How can I use rvest to login into websites that don't have visible login forms? For example, the Washington Post's website has a sign in box on the top right of the page. Once clicked, a form appears where you can sign in.
library(rvest)
url <- 'https://www.rotary.org/myrotary/en'
url2 <- 'https://stackoverflow.com/users/login?ssrc=head&returnurl=http%3a%2f%2fstackoverflow.com%2f'
url3 <- 'https://www.washingtonpost.com/?noredirect=on'
If I get the structure of the forms on StackOverflow's login page,
pg_session <- html_session(url2)
html_form(pg_session) %>% str
List of 2
$ :List of 5
..$ name : chr "search"
..$ method : chr "GET"
..$ url : chr "/search"
..$ enctype: chr "form"
..$ fields :List of 2
.. ..$ q :List of 7
.. .. ..$ name : chr "q"
.. .. ..$ type : chr "text"
.. .. ..$ value : chr ""
.. .. ..$ checked : NULL
.. .. ..$ disabled: NULL
.. .. ..$ readonly: NULL
.. .. ..$ required: logi FALSE
.. .. ..- attr(*, "class")= chr "input"
.. ..$ <unnamed>:List of 7
.. .. ..$ name : chr "<unnamed>"
.. .. ..$ type : chr "submit"
.. .. ..$ value : NULL
.. .. ..$ checked : NULL
.. .. ..$ disabled: NULL
.. .. ..$ readonly: NULL
.. .. ..$ required: logi FALSE
.. .. ..- attr(*, "class")= chr "button"
.. ..- attr(*, "class")= chr "fields"
..- attr(*, "class")= chr "form"
$ :List of 5
..$ name : chr "login-form"
..$ method : chr "POST"
..$ url : chr "/users/login?ssrc=head&returnurl=http%3a%2f%2fstackoverflow.com%2f"
..$ enctype: chr "form"
..$ fields :List of 7
.. ..$ fkey :List of 7
.. .. ..$ name : chr "fkey"
.. .. ..$ type : chr "hidden"
.. .. ..$ value : chr "d5f8c65b7d92b368b4b58e43e59fd9d82cb4436bac4a6d430771d50b85e771aa"
.. .. ..$ checked : NULL
.. .. ..$ disabled: NULL
.. .. ..$ readonly: NULL
.. .. ..$ required: logi FALSE
.. .. ..- attr(*, "class")= chr "input"
.. ..$ ssrc :List of 7
.. .. ..$ name : chr "ssrc"
.. .. ..$ type : chr "hidden"
.. .. ..$ value : chr "head"
.. .. ..$ checked : NULL
.. .. ..$ disabled: NULL
.. .. ..$ readonly: NULL
.. .. ..$ required: logi FALSE
.. .. ..- attr(*, "class")= chr "input"
.. ..$ email :List of 7
.. .. ..$ name : chr "email"
.. .. ..$ type : chr "email"
.. .. ..$ value : NULL
.. .. ..$ checked : NULL
.. .. ..$ disabled: NULL
.. .. ..$ readonly: NULL
.. .. ..$ required: logi FALSE
.. .. ..- attr(*, "class")= chr "input"
.. ..$ password :List of 7
.. .. ..$ name : chr "password"
.. .. ..$ type : chr "password"
.. .. ..$ value : NULL
.. .. ..$ checked : NULL
.. .. ..$ disabled: NULL
.. .. ..$ readonly: NULL
.. .. ..$ required: logi FALSE
.. .. ..- attr(*, "class")= chr "input"
.. ..$ submit-button:List of 7
.. .. ..$ name : chr "submit-button"
.. .. ..$ type : NULL
.. .. ..$ value : NULL
.. .. ..$ checked : NULL
.. .. ..$ disabled: NULL
.. .. ..$ readonly: NULL
.. .. ..$ required: logi FALSE
.. .. ..- attr(*, "class")= chr "button"
.. ..$ oauth_version:List of 7
.. .. ..$ name : chr "oauth_version"
.. .. ..$ type : chr "hidden"
.. .. ..$ value : NULL
.. .. ..$ checked : NULL
.. .. ..$ disabled: NULL
.. .. ..$ readonly: NULL
.. .. ..$ required: logi FALSE
.. .. ..- attr(*, "class")= chr "input"
.. ..$ oauth_server :List of 7
.. .. ..$ name : chr "oauth_server"
.. .. ..$ type : chr "hidden"
.. .. ..$ value : NULL
.. .. ..$ checked : NULL
.. .. ..$ disabled: NULL
.. .. ..$ readonly: NULL
.. .. ..$ required: logi FALSE
.. .. ..- attr(*, "class")= chr "input"
.. ..- attr(*, "class")= chr "fields"
..- attr(*, "class")= chr "form"
, I can clearly locate where to fill out my email and password. However, I can't find it in the structure of the forms on the Washington Post's home page, which makes it difficult to call the form I need.
pg_session <- html_session(url3)
html_form(pg_session) %>% str
List of 1
$ :List of 5
..$ name : chr "search-form"
..$ method : chr "GET"
..$ url : chr "//www.washingtonpost.com/newssearch/"
..$ enctype: chr "form"
..$ fields :List of 1
.. ..$ query:List of 7
.. .. ..$ name : chr "query"
.. .. ..$ type : chr "text"
.. .. ..$ value : NULL
.. .. ..$ checked : NULL
.. .. ..$ disabled: NULL
.. .. ..$ readonly: NULL
.. .. ..$ required: logi FALSE
.. .. ..- attr(*, "class")= chr "input"
.. ..- attr(*, "class")= chr "fields"
..- attr(*, "class")= chr "form"
My particular case is to log in to this site, however the Washington Post's pop up log in seems similar enough that it would be the same procedure. How can I call these pop-up log ins?
*I am not too familiar with html, so if there are any better terms to use or ways to phrase it, feel free to correct me.