Cookbook/LinkingColumns
(contributed by Morgan Stanley)
Contents |
Linking Columns
Introduction
The concept of a link column is closely related to a foreign key column, in that it provides linkage between the values of a column in a table to the values in a column in a second table. The difference is that whereas a foreign key column is an enumeration over the key column of a keyed table, a link column comprises indices into an arbitrary column of an arbitrary table.
A link column is useful in situations where a key column is not available. For example, a table can contain a link to itself in order to create a parent-child relationship. You can also use links to create 'foreign key' relationships between splayed tables, where foreign keys are not possible since a keyed table cannot be splayed.
Memory Tables
We begin with the situation in which both tables reside in memory. In our first example, we use a link column from a table to itself to create a parent-child relationship. Starting with t,
q)t:([] id:101 102 103 104; v:1.1 2.2 3.3 4.4)
To create the column parent, we look up the values in the key column using ? and then declare the link using ! instead of $ as we would for a foreign key enumeration.
q)update parent:`t!id?101 101 102 102 from `t `t q)t id v parent -------------- 101 1.1 0 102 2.2 0 103 3.3 1 104 4.4 1
Observe that meta displays the target table of the link in the f column, just as it does for a foreign key.
q)meta t c | t f a ------| ----- id | i v | f parent| i t
And just as with a foreign key, we can use dot notation on the link column to follow the link and access any column in the linked table.
q)select id, parentid:parent.id from t id parentid ------------ 101 101 102 101 103 102 104 102
Next, we create a link between two columns of enumerated symbols, since this occurs frequently in practice. The table t1 has a column c1 enumerated over sym.
q)sym:() q)show t1:([] c1:`sym?`c`b`a; c2: 10 20 30) c1 c2 ----- c 10 b 20 a 30
The table t2 has a column c3 also enumerated over sym, and whose values are drawn from those of column c1 in t1.
q)show t2:([] c3:`sym?`a`b`a`c; c4: 1. 2. 3. 4.) c3 c4 ----- a 1 b 2 a 3 c 4
As before, we use ? to create a vector of indices and we use ! in place of $ to create the link.
q)update t1link:`t1!t1.c1?c3 from `t2
Again the f column of meta indicates the table over which the link is created.
q)meta t2 c | t f a ------| ------ c3 | s c4 | f t1link| i t1
Now we can issue queries that traverse the link using dot notation.
q)select c3, t1link.c2 from t2 c3 c2 ----- a 30 b 20 a 30 c 10
Splayed Tables
We consider the case in which the table t1 has already been splayed on disk and mapped into the q session. Note that dot notation does not work for splayed tables when creating the link.
q)`:c:/Data/db/t1/ set .Q.en[`:c:/Data/db/; ([] c1:`c`b`a; c2: 10 20 30)] `:c:/Data/db/t1/ q)\l c:/Data/db q)meta t1 c | t f a --| ----- c1| s c2| i
We shall create a link column in table t2 as it is splayed. (This should be done on each append if you are creating t2 incrementally on disk.)
q)temp:.Q.en[`:c:/Data/db/; ([] c3:`a`b`a`c; c4: 1. 2. 3. 4.)] q)`:c:/Data/db/t2/ set update t1link:`t1!t1[`c1]?c3 from temp `:c:/Data/db/t2/
We remap and check meta,
q)\l c:/Data/db q)meta t2 c | t f a ------| ------ c3 | s c4 | f t1link| i t1
Now we can issue a query across the link,
q)select t1link.c2, c3 from t2 c2 c3 ----- 30 a 20 b 30 a 10 c
Next, we consider the case when t1 and t2 have both been splayed.
q)`:c:/Data/db/t1/ set .Q.en[`:c:/Data/db/; ([] c1:`c`b`a; c2: 10 20 30)] `:c:/Data/db/t1/ q)`:c:/Data/db/t2/ set .Q.en[`:c:/Data/db/; ([] c3:`a`b`a`c; c4: 1. 2. 3. 4.)] `:c:/Data/db/t2/
First we create the link when both tables have been mapped into memory.
q)\l c:/Data/db
The link column can be created as before, but we must update the splayed files of t2 manually.
q)`:c:/Data/db/t2/t1link set `t1!t1[`c1]?t2`c3 `:c:/Data/db/t2/t1link q)`:c:/Data/db/t2/.d set (cols t2),`t1link `:c:/Data/db/t2/.d
We remap and issue the query as before
q)\l c:/Data/db q)meta t2 c | t f a ------| ------ c3 | s c4 | f t1link| i t1 q)select t1link.c2, c3 from t2 c2 c3 ----- 30 a 20 b 30 a 10 c
Finally, we consider two splayed tables that have not been mapped.
q)`:c:/Data/db/t1/ set .Q.en[`:c:/Data/db/; ([] c1:`c`b`a; c2: 10 20 30)] `:c:/Data/db/t1/ q)`:c:/Data/db/t2/ set .Q.en[`:c:/Data/db/; ([] c3:`a`b`a`c; c4: 1. 2. 3. 4.)] `:c:/Data/db/t2/
We retrieve the column lists manually and proceed as before.
q)`:c:/Data/db/t2/t1link set `t1!(get `:c:/Data/db/t1/c1)?get `:c:/Data/db/t2/c3 `:c:/Data/db/t2/t1link q)colst2:get `:c:/Data/db/t2/.d q)`:c:/Data/db/t2/.d set colst2,`t1link `:c:/Data/db/t2/.d
Partitioned Tables
Partitioned tables can have link columns provided the links do not span partitions. In particular, you cannot link across days for a table partitioned by date.
Creating a link column in a partitioned table is best done as each partition is written, in which case the process reduces to that for splayed tables.
In our first example, we create a link between non-symbol columns in the simple partitioned tables t1 and t2.
We create the first day's tables with the link and save them to a partition.
q)t1:([] id:101 102 103; v:1.1 2.2 3.3) q)t2:([] t1link:`t1!t1[`id]?103 101 101 102; n:10 20 30 40) q)`:c:/Temp/db/2009.01.01/t1/ set t1 `:c:/Temp/db/2009.01.01/t1/ q)`:c:/Temp/db/2009.01.01/t2/ set t2 `:c:/Temp/db/2009.01.01/t2/
We do the same for the second day.
q)t1:([] id:104 105; v:4.4 5.5) q)t2:([] t1link:`t1!t1[`id]?105 104 104; n:50 60 70) q)`:c:/Temp/db/2009.01.02/t1/ set t1 `:c:/Temp/db/2009.01.02/t1/ q)`:c:/Temp/db/2009.01.02/t2/ set t2 `:c:/Temp/db/2009.01.02/t2/
Finally, we restart q, map the tables and execute a query across the link.
>q KDB+ 2.4 2008.10.15 Copyright (C) 1993-2008 Kx Systems... q)\l c:/Temp/db q)select date,n,t1link.v from t2 where date within 2009.01.01 2009.01.02 date n v ----------------- 2009.01.01 10 3.3 2009.01.01 20 1.1 2009.01.01 30 1.1 2009.01.01 40 2.2 2009.01.02 50 5.5 2009.01.02 60 4.4 2009.01.02 70 4.4
The final example is similar except that it creates a link over enumerated symbol columns.
q)/ day 1 q)t1:([] c1:`c`b`a; c2: 10 20 30) q)`:c:/Temp/db/2009.01.01/t1/ set .Q.en[`:c:/Temp/db/; t1] `:c:/Temp/db/2009.01.01/t1/ q)t2:([] c3:`a`b`a`c; c4: 1. 2. 3. 4.) q)`:c:/Temp/db/2009.01.01/t2/ set .Q.en[`:c:/Temp/db/; update t1link:`t1!t1[`c1]?c2 from t2] `:c:/Temp/db/2009.01.01/t2/ q)/ day 2 q)t1:([] c1:`d`a; c2: 40 50) q)`:c:/Temp/db/2009.01.02/t1/ set .Q.en[`:c:/Temp/db/; t1] `:c:/Temp/db/2009.01.02/t1/ q)t2:([] c3:`d`a`d; c4:5. 6. 7.) q)`:c:/Temp/db/2009.01.02/t2/ set .Q.en[`:c:/Temp/db/; update t1link:`t1!t1[`c1]?c2 from t2] `:c:/Temp/db/2009.01.02/t2/ q)/ remap q)\l c:\Temp\db q)select c3,t1link.c2,c4 from t2 where date within 2009.01.01 2009.01.02 c3 c2 c4 -------- a 30 1 b 20 2 a 30 3 c 10 4 d 40 5 a 50 6 d 40 7


Hide scroll bar
Inspection Timer
Change background
Download solves
Load Solves
Fork me
Best: -
Average All: -
Average 5: -
00:00.00
Press SPACE to start/stop the timer
Press Enter to save the new Solve class
Undo delete


public abstract class GMLShape extends GMLObject
| Modifier | Constructor and Description |
|---|---|
protected |
GMLShape(int id)
Construct a GMLShape.
|
protected |
GMLShape(int id,
java.util.List<GMLDirectedEdge> edges)
Construct a GMLShape.
|
protected |
GMLShape(int id,
java.util.List<GMLDirectedEdge> edges,
java.util.List<java.lang.Integer> neighbours)
Construct a GMLShape.
|
| Modifier and Type | Method and Description |
|---|---|
java.awt.geom.Rectangle2D |
getBounds()
Get the bounds of this shape.
|
double |
getCentreX()
Get the x coordinate of the centroid of this shape.
|
double |
getCentreY()
Get the y coordinate of the centroid of this shape.
|
Point2D |
getCentroid()
Get the centroid of this shape.
|
java.util.List<GMLCoordinates> |
getCoordinates()
Get the coordinates of the apexes of this shape.
|
java.util.List<GMLDirectedEdge> |
getEdges()
Get the edges of this shape.
|
java.lang.Integer |
getNeighbour(GMLDirectedEdge edge)
Get the ID of the neighbour through a particular edge.
|
java.lang.Integer |
getNeighbour(GMLEdge edge)
Get the ID of the neighbour through a particular edge.
|
java.util.List<GMLCoordinates> |
getUnderlyingCoordinates()
Get the coordinates of the edges that make up this shape.
|
java.util.List<GMLNode> |
getUnderlyingNodes()
Get the nodes of the edges that make up this shape.
|
boolean |
hasNeighbour(GMLDirectedEdge edge)
Find out if an edge has a neighbour.
|
boolean |
hasNeighbour(GMLEdge edge)
Find out if an edge has a neighbour.
|
void |
removeEdge(GMLEdge edge)
Remove an edge from this shape.
|
void |
reorderEdges(java.util.List<GMLDirectedEdge> newEdges)
Reorder the list of edges.
|
void |
replaceEdge(GMLDirectedEdge oldEdge,
GMLDirectedEdge... newEdges)
Replace a GMLDirectedEdge with a set of new edges.
|
void |
setCoordinates(java.util.List<GMLCoordinates> newPoints)
Set the coordinates of the apexes of this shape.
|
void |
setEdges(java.util.List<GMLDirectedEdge> newEdges)
Set the list of edges.
|
void |
setNeighbour(GMLDirectedEdge edge,
java.lang.Integer neighbour)
Set the ID of the neighbour through a particular edge.
|
void |
setNeighbour(GMLEdge edge,
java.lang.Integer neighbour)
Set the ID of the neighbour through a particular edge.
|
protected GMLShape(int id)
id
- The ID of the shape.protected GMLShape(int id, java.util.List<GMLDirectedEdge> edges)
id
- The ID of the shape.edges
- The edges of the shape.protected GMLShape(int id, java.util.List<GMLDirectedEdge> edges, java.util.List<java.lang.Integer> neighbours)
id
- The ID of the shape.edges
- The edges of the shape.neighbours
- The neighbours of each edge.public java.util.List<GMLDirectedEdge> getEdges()
public void setEdges(java.util.List<GMLDirectedEdge> newEdges)
newEdges
- The new edge list.public void reorderEdges(java.util.List<GMLDirectedEdge> newEdges)
newEdges
- The reordered edge list.public void replaceEdge(GMLDirectedEdge oldEdge, GMLDirectedEdge... newEdges)
oldEdge
- The edge to replace.newEdges
- The new edges.public void removeEdge(GMLEdge edge)
edge
- The underlying edge to remove.public java.lang.Integer getNeighbour(GMLDirectedEdge edge)
edge
- The edge to look up.public void setNeighbour(GMLDirectedEdge edge, java.lang.Integer neighbour)
edge
- The edge to set the neighbour of.neighbour
- The new neighbour ID for that edge. This may be null.public boolean hasNeighbour(GMLDirectedEdge edge)
edge
- The edge to look up.public java.lang.Integer getNeighbour(GMLEdge edge)
edge
- The edge to look up.public void setNeighbour(GMLEdge edge, java.lang.Integer neighbour)
edge
- The edge to set the neighbour of.neighbour
- The new neighbour ID for that edge. This may be null.public boolean hasNeighbour(GMLEdge edge)
edge
- The edge to look up.public java.util.List<GMLCoordinates> getUnderlyingCoordinates()
public java.util.List<GMLNode> getUnderlyingNodes()
public java.util.List<GMLCoordinates> getCoordinates()
public void setCoordinates(java.util.List<GMLCoordinates> newPoints)
newPoints
- The new apex coordinates.public double getCentreX()
public double getCentreY()
public java.awt.geom.Rectangle2D getBounds()
public Point2D getCentroid()


NZD/USD advances beyond 0.6430 on renewed US-China trade optimism
by Eren Sengezer- Next round of US-China trade talks could reportedly take place before Thanksgiving.
- Credit Card Spending data from New Zealand came in below market expectations.
- Coming up: Weekly Jobless Claims and Existing Home Sales data from US.
The NZD/USD pair tested the 0.6400 mark for the second straight day on Thursday but didn't have a difficult time reversing its direction. As of writing, the pair was trading at its highest level since November 4th at 0.6336, adding 0.28% on a daily basis.
NZD continues to react to US-China trade headlines
In the absence of significant macroeconomic drivers, developments surrounding the United States (US)-China trade dispute continue to drive the pair's action. Chinese Vice Premier Liu He on Thursday noted that he was confident about reaching the phase one of the trade deal.
Additionally, the Wall Street Journal reported that China has invited Secretary Treasury Mnuchin and Trade Representative Lighthizer to China with hopes of the next round of face-to-face talks taking place before Thanksgiving.
Meanwhile, the only data from New Zealand revealed that Credit Card Spending in October increased by 2.5% on a yearly basis and fell short of the market expectation for an increase of 5.5%.
On the other hand, after the Federal Open Market Committee's (FOMC) October meeting minutes on Wednesday reaffirmed the wait-and-see approach regarding the near-term policy outlook, the greenback remained stuck in its weekly range below the 98 handle. Later in the session, weekly Jobless Claims data and Existing Home Sales figures from the United States will be looked upon for fresh impetus.
Technical levels to consider
NZD/USD
| Overview | |
|---|---|
| Today last price | 0.6436 |
| Today Daily Change | 0.0022 |
| Today Daily Change % | 0.34 |
| Today daily open | 0.6414 |
| Trends | |
|---|---|
| Daily SMA20 | 0.6381 |
| Daily SMA50 | 0.6345 |
| Daily SMA100 | 0.6433 |
| Daily SMA200 | 0.6564 |
| Levels | |
|---|---|
| Previous Daily High | 0.6437 |
| Previous Daily Low | 0.6403 |
| Previous Weekly High | 0.642 |
| Previous Weekly Low | 0.6324 |
| Previous Monthly High | 0.6437 |
| Previous Monthly Low | 0.6204 |
| Daily Fibonacci 38.2% | 0.6416 |
| Daily Fibonacci 61.8% | 0.6424 |
| Daily Pivot Point S1 | 0.6399 |
| Daily Pivot Point S2 | 0.6384 |
| Daily Pivot Point S3 | 0.6365 |
| Daily Pivot Point R1 | 0.6433 |
| Daily Pivot Point R2 | 0.6452 |
| Daily Pivot Point R3 | 0.6467 |


CameraProjectionY()
Syntax
Result = CameraProjectionY(#Camera, x, y, z)Description
Returns the 'y' position, in pixels, of a 3D point on the specified #Camera. If the point is outside of the camera current view, it returns -1. This is very useful to map 3D points to 2D screen.
Supported OS
All


Nodes
IP Address
Port
Last Relay
Version
Client
Country
{{info._id}}
{{info.port}}
{{info.lastsend*1000 | timeAgo}}
{{info.version}}
{{info.client}}
{{info.country_code}}


@*
* Copyright 2023 HM Revenue & Customs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*@
@import uk.gov.hmrc.hmrcfrontend.views.viewmodels.language.En
@import uk.gov.hmrc.hmrcfrontend.views.viewmodels.footer.Footer
@import uk.gov.hmrc.apirevocationfrontend.config.{FooterConfig, FrontendAppConfig}
@import uk.gov.hmrc.govukfrontend.views.html.components.GovukLayout
@this(
govukLayout: GovukLayout,
hmrcHeader: HmrcHeader,
hmrcFooter: HmrcFooter,
hmrcHead: HmrcHead
)
@(title: Option[String] = None)(contentBlock: Html)(implicit request : Request[_], messages: Messages, applicationConfig: FrontendAppConfig, footerConfig: FooterConfig)
@serviceInfoContent = {}
@scriptElem = {
}
@beforeContent = {
beta
This is a new service – your feedback will help us to improve it.
}
@mainContentDefault = {
@contentBlock
Is this page not working properly?
}
@siteFooter = {
@hmrcFooter(new Footer(meta = Some(
Meta(
items = Some(
Seq(
FooterItem(text = Some("Cookies"), href = Some(s"${footerConfig.apiDocumentationFrontendUrl}/api-documentation/docs/help/cookies")),
FooterItem(text = Some("Accessibility statement"), href = Some(s"${footerConfig.platformFrontendHost}/accessibility-statement/manage-permissions-for-tax-software?referrerUrl=${helper.urlEncode(request.uri)}")),
FooterItem(text = Some("Privacy Policy"), href = Some(s"${footerConfig.thirdPartyDeveloperFrontendUrl}/api-documentation/docs/help/privacy")),
FooterItem(text = Some("Terms and conditions"), href = Some(s"${footerConfig.thirdPartyDeveloperFrontendUrl}/api-documentation/docs/help/terms-and-conditions")),
FooterItem(text = Some("Help using GOV.UK "), href = Some("https://www.gov.uk/help"))
)
)
)
), language = En))
}
@govukLayout(
pageTitle = title,
headBlock = Some(hmrcHead()),
headerBlock = Some(hmrcHeader(Header(
homepageUrl ="https://www.gov.uk",
serviceName = Some(messages("service.name")),
navigation = None,
serviceUrl = "",
displayHmrcBanner = false,
containerClasses = "govuk-width-container",
signOutHref = None,
language = En
))),
beforeContentBlock = Some(beforeContent),
scriptsBlock = Some(scriptElem),
footerBlock = Some(siteFooter),
assetPath = None,
cspNonce = None
)(mainContentDefault)


We insist on making the Deerioca from scratch: making the dough, kneading and rolling the dough into small balls, this procedure creates better texture and aroma for the tapioca. Each bite is unique, satisfying the craving for the perfect taste.
堅持從麵團、拍打、手揉到成形，增加珍珠咀嚼時的香氣口感，食味不完美的形、不一致的口味是唇齒的渴望。
SubTea provide different milk tea services, you can choose your favorite topping in your milk tea. Mix & Match your milk tea now!
SubTea提供不一样的服务,您可以根据自己的喜好来添加配料搭配奶茶！
Specials Drinks of SubTea
Choose Your Own Likely Base, Flavour(Fruity/Milky) and Topping
We also provide a variety of different drinks, please click the menu to check it out!


You can also fetch the data from a server using a function that returns a promise.
The angular-datatables
provides the helper DTOptionsBuilder.withFnPromise(fnPromise)
and the helper DTColumnBuilder
that lets you build the datatables options for each column.
See the API for the complete list of methods of the helper.


[gecode-users] Linking to Gecode with Microsoft Visual C++
Christian Schulte
cschulte at kth.se
Tue Sep 2 16:50:45 CEST 2008
As a slight addition: first, our thanks to Jan Kelbel, for helping us to
reproduce and analyze the bug.
Then, in 3.0 Gecode will use auto-linking with MSVC: so it is sufficient to
give the library directory. The respective libraries will be found
automatically by the linker.
Christian
--
Christian Schulte, www.ict.kth.se/~cschulte/
-----Original Message-----
From: users-bounces at gecode.org [mailto:users-bounces at gecode.org] On Behalf
Of Guido Tack
Sent: Tuesday, September 02, 2008 4:46 PM
To: gecode users list
Subject: [gecode-users] Linking to Gecode with Microsoft Visual C++
Hi everyone!
We had a bit of trouble trying to link to the binary Gecode
distribution from a Microsoft Visual Studio C++ project. First of
all, here's what you have to set up in the properties dialog of your
"Solution":
* Configuration Properties, C++, General, set the Additional Include
Directories to <Program Files>\Gecode
* Configuration Properties, Linker, General, set the Additional
Library Directories to <Program Files>\Gecode\lib
* Configuration Properties, Linker, Input, set the Additional
Dependencies to GecodeSupport.lib GecodeKernel.lib GecodeSearch.lib
etc. (all the Gecode libraries that you want to link against)
That should do the trick, except that only a release build works
properly at the moment. If you build your project using a Debug
configuration instead, your program will crash with "bad alloc" errors.
Apparently, inlining doesn't work too well when linking against
different libraries (i.e., linking Gecode with /MD while linking your
program with /MDd). So, for the time being, you will have to compile
your program as a Release build, or compile your own version of Gecode
with debug turned on. We're looking into this issue, and we'll try to
produce (optimized) libraries that can be used in a Debug build for
the next version of Gecode.
Cheers,
Guido
_______________________________________________
Gecode users mailing list
users at gecode.org
https://www.gecode.org/mailman/listinfo/gecode-users
More information about the gecode-users
mailing list


How to navigate to, select or manage folders and files using the Resource Manager provided with the TelerikEditorProvider for the RTE. The Resource Manager is commonly used for the Image Manager, Document Manager, Flash Manager, Media Manager and Template Manager tools of the RadEditor.
Note: Access to some tools is restricted by role.
The Resource Manager consists of the following toolbar and windows: Resource Manager Toolbar, Folder Window, Filename Window, Preview/Properties Window.
Resource Manager Toolbar
| Tool | Icon | Description |
|---|---|---|
| Back | Go back by one folder in the Folders window. | |
| Forward | Move forward by one folder in the Folders window. | |
| Refresh | Refresh to retrieve newly updated files. | |
| New Folder |
In the Folders window, select the parent folder and then click the New Folder button. |
|
| Delete |
|
|
| Upload | In the Folders window, select the folder where the file will be uploaded to and then click the Upload button. | |
Folder Window: This window displays the folders of the Digital Asset Management module that is located on the Admin > File Management page in a hierarchical tree structure. Select a folder to view its sub-folders and/or files in the Filename Window. Folders can be moved by dragging into a different folder. Right click a folder to perform Delete, Rename, New Folder or Upload.
Filename Window: Displays a list of the folders and/or files within the selected folder. Select a file to view a preview and/or properties information in the Preview/Properties Window. Files can be moved by dragging into a different folder. Right click an image or folder to perform Delete, Rename, New Folder or Upload.
Tip: Click the Collapse/Expand the left pane button to hide/show the Folder Window. This is useful once you have navigated to the required folder as it provides additional space to view files details.
Preview/Properties Window: Displays a preview and/or properties of the selected file. Properties can be modified as required.


Check out some gifts that will make any asian parent proud!
Since 1766 BCE around the time of the Xia Dynasty, chopsticks have been a stable utensil for asian race. Not everyone has mastered the art of the these simple looking sticks however. But NOW YOU CAN! Check out these awesome chopstick trainers which will make you a master of the chopstick! Easy to clip on to any chopstick! Perfect gift for your white friends that want to appreciate your asian culture more. No more stabbing with the pointy part!
Yellow on the outside, white on the inside. It's your favorite childhood snack / slightly offensive label! Embrace the novelty of being an asian without the asian stereotypes. Now you can call yourself a twinkie before anyone else does and it'll hurt less!
And you thought Pikachu couldn't get any cuter! Now it (he?) can, by wearing his face right above your head! Not only can you wear the most well-known and adorable pokemon as an accessory, but you can also make him dance! Pull right, then left, then right again to make him playfully dance on your head! Cuter than a mad jigglypuff I'd say!
The perfect halloween costome doesn't ex- NANI?!?  Everyone will be (rice) rolling for this awesome hat! Hell, who needs to wait Halloween? Be the rice of any party. Buy this hat now. Or for a friend to embarass them.


Analog Devices AD9984A¶
The Analog Devices AD9984A is an analog-to-digital converter (ADC) specialised for video digitisation. Full details, including the datasheet, can be found on the Analog Devices AD9984A product page.
The specific part is the AD9984AKSTZ-140, an LQFP-packaged part supporting a maximum pixel clock of 140MHz.
The key points of the integration of this IC into the design are:
An external pixel clock (derived from the Amiga’s colour clock) is always used.
The device supports two sets of inputs (RGB+sync); only input set 0 is used in this design.
Power supply and voltages¶
The AD9984A requires four power inputs:
VD, 1.8V. This is the main power supply. From the datasheet: These pins supply power to the main elements of the circuit. They should be as quiet and as filtered as possible.
VDD, 1.8 - 3.3V. This is the digital output power supply. From the datasheet: A large number of output pins (up to 35) switching at high speed (up to 170 MHz) generates large amounts of power supply transients (noise). These supply pins are identified separately from the VD pins. As a result, special care must be taken to minimize output noise transferred into the sensitive analog circuitry. If the AD9984A is interfacing with lower voltage logic, VDD can be connected to a lower supply voltage (as low as 1.8 V) for compatibility.
PVD, 1.8V. This is the PLL power supply. From the datasheet: The most sensitive portion of the AD9984A is the clock generation circuitry. These pins provide power to the clock PLL and help the user design for optimal performance. The designer should provide quiet, noise-free power to these pins.
DAVDD, 1.8V. This is the digital input power supply. From the datasheet: This supplies power to the digital logic. It is recommended to connect this pin to the VD supply.
The FPGA module’s GPIO pins all use the 3.3V I/O standard, therefore, VDD will be connected to the 3.3V supply from the FPGA module. There is the recommendation to connect VD and DAVDD to the same 1.8V supply. PVD is also 1.8V and we will connect this to the same supply on the assumption (yet to be tested) that this will be adequate (after all, we will not be using the PLL in this design). To get a 1.8V supply, the simplest solution will be a basic voltage divider of the 3.3V supply from the FPGA module.
Digital inputs can tolerate up to 5V. This means that the Amiga’s HSYNC and VSYNC can be connected directly, if required.
Input pins¶
The following inputs are used (with reference to Table 4 in the datasheet):
RAIN0, GAIN0, BAIN0 - analog red, green and blue signals from the Amiga. Note that these must be terminated and coupled according to Figure 4 of the datasheet.
HSYNC0 and VSYNC0 - these are connected to the Amiga’s HSYNC and VSYNC. These do not need termination, although TBD if buffering is appropriate (in the current design they are connected directly).
EXTCK - this is connected to the PLL output and represents the Amiga’s pixel clock.
PWRDN - TBC
The following inputs are not used in this design:
RAIN1, GAIN1, BAIN1
HSYNC1 and VSYNC1
SOGIN0 and SOGIN1 - not used and left unconnected in accordance with the datasheet.
CLAMP - not used and left unconnected in accordance with the datasheet.
COAST - this shares a pin with EXTCK. The COAST function of the pin is ignored.
Reference pins¶
REFLO and REFHI must be connected to each other with a 10µF capacitor, as shown in Figure 6 of the datasheet.
FILT is required for the best stability of the AD9984A’s internal PLL. We do not use the internal PLL, but the datasheet is not clear if this means the circuit to do this is optional. Since the required circuit is simple (see Figure 8 in the datasheet), we implement it for completeness and to allow the option of using the internal PLL in future.
Control pins¶
SDA and SCL are standard I2C pins, which are passed through to the FPGA module directly.


---
layout: post
title: Things that annoy me about Linux on my laptop
tags:
- Linux
status: publish
type: post
published: true
meta: {}
---
When I first became self-employed I very diligently (well, fairly diligently) researched the market for a laptop machine and was delighted to find a HP nx6125 for a neat price (A$1700), I also researched Linux compatibility and whilst there are issues, by and large it works. However there are some things that continue to really annoy me.
- I cannot hibernate or sleep. I suspect a problem with my video driver although I appear to have the ATI driver installed correctly and other people are reporting success with sleep mode.
- I have USB headphones that work perfectly with Skype and ALSA. However all other sound (e.g. Music CD's) insists on coming out of the speakers. BTW, if you have audio jacks on your PC don't buy USB headphones -- they are bulky and take up a USB socket
- It took me 6 months to get Wireless working :-(, but at least it works now. Thanks to the Ndiswrapper team for saving my life
- I cannot get the sychronisation for my Pocket PC mobile phone working
- Nothing to do with Linux, but because of cost I compromised and accepted a machine with a trackerpad instead of a G spot. After 6 months I can say that the IBM G spot (also available on some HP machines) is far superior.


Cereal Bar Game
Instructions (opens in a new tab)
Leaderboard
Place
Score
{% for game in leaders %}
{{game[0]}}
{{game[1]}}
{% endfor %}


I am a self-taught programmer and my educational experience includes a recently completed engineering degree (mechanical) which contributed greatly to my development of skills such as software development and teamwork. During my final year project, I worked on developing control system for Quadcopter, C++ was chosen to program the Arduino board.
After graduating, I focused more on writing software rather than designing control systems. Thus, I have completed web development bootcamp course. At the end of this course, I have built smart-website that can detect face in any picture and deploy the website on Heroku cloud platform. I consider myself an adaptable and efficient team player with excellent communication and delivery at all levels.
View linkedinThe project idea is to create a website that has similar face detection feature like facebook face-tag. Different tools and technology is used to build the website.
For inquiries or buisness opportunity
Email


--- layout: archive title: Zulip Chat Archive permalink: /stream/113488-general/topic/Relationship.20between.20repos.20lean.20and.20lean-nightly.html ---
I am confused about the relationship between the following two repos:
https://github.com/leanprover/lean
https://github.com/leanprover/lean-nightly
I thought the latter contains snapshots of the former which also appear as nightly builds. But the latest nightly in:
https://github.com/leanprover/lean-nightly/releases
commit: 5f38fd46d102e81ea798b97d18825ca583150aca
does not appear to exist in the lean repo. Was my understanding wrong?
Thanks!
I believe that hash is a commit to the lean-nightly
project which is not a fork of lean
it is used more like some server space. When travis is done building lean
, it pushes a release lean-nightly
which is not a commit in lean-nightly
These are still test releases. I will remove them once the change is live.
What about the nightlies here?
https://leanprover.github.io/download/
How are they related to the ones in lean-nightly?
Thanks!
The download page will link to the releases page when the change is done
{% endraw %}Last updated: Apr 24 2020 at 19:02 UTC


 Searching for simple, effective recipes for one can be a fun challenge, especially when you try to emulate something you see in a restaurant or cafe.
Presenting a sample of the good ol’ days, if we can call them that, the Black bean burrito. I really didn’t want to leave the house this morning, and I managed to find black beans, mushrooms, onions, some greens, oat wraps and this is very important ??? cheese ??? so I set to work.
Witness the end results taken with my phone camera. And yes, that’s Whittard’s Mango & Passionfruit Iced tea gleaming by the side. Yes, iced tea can gleam, thank you very much.


CAL + Ledger: Sign a message (Bitcoin)
Initate
From:
Message:
Sign
Result:
Pay to address
To:
Value:
Send
Result:
For errors and logs, check console


Artificial life ecosystem.
Atmosphere simulator implemented by cellular automata.
Orbital motion & orbital velocity demo.
Objects with multiple gravity sources.
An oil painting like generative art based on artificial life ecosystem.
Based on ALife Core. The lines connect between a parent and its children.
Copy of Casey Reas's Process series.
Expanded L-System
The circle size represents how long has it been alive.
Working on it


Please read our documentation
For utilizing this Template, you would require fundamental comprehension of HTML, CSS and Angular, if you don't mind give your inquiry a brisk Google or visit W3Schools as topic issues get top need.
You can seen above a arrangement of files for this project. You can discover this project by this folders
NOTE: dist is final folder to upload on your server we are added just for understand this template. Run command: ng build


Chapter 4 Experiment: Within one-way
This section outlines a workflow appropriate for when you have a repeated measures design with a single repeated measurs predictor. The data corresponds to a design where the researcher is interested in comparing run times (elapsed_time) across three different occasions (march/may/june).
To Begin:
Use the Files tab to confirm you have the data: data_ex_within.csv
Start a new script for this example. Don’t forget to start the script name with “script_”.
# Date: YYYY-MM-DD
# Name: your name here
# Example: Within-participant experiment
# Load data
library(tidyverse)
my_missing_value_codes <- c("-999", "", "NA")
raw_data_within <- read_csv(file = "data_ex_within.csv",
na = my_missing_value_codes)
## Parsed with column specification:
## cols(
## id = col_double(),
## sex = col_character(),
## march = col_double(),
## may = col_double(),
## july = col_double()
## )
We load the intial data into a raw_data_within but immediately make a copy we will work with called analytic_data_within. It’s good to keep a copy of the raw data for reference if you encounter problems.
After loading the data we do initial cleaning to remove empty row/columns and ensure proper naming for columns:
library(janitor)
# Initial cleaning
analytic_data_within <- analytic_data_within %>%
remove_empty("rows") %>%
remove_empty("cols") %>%
clean_names()
You can confirm the column names following our naming convention with the glimpse command - and see the data type for each column.
## Rows: 6
## Columns: 5
## $ id <dbl> 1, 2, 3, 4, 5, 6
## $ sex <chr> "male", "female", "male", "female", "male", "female"
## $ march <dbl> 40, 35, 38, 33, 42, 36
## $ may <dbl> 37, 32, 35, 30, 39, 33
## $ july <dbl> 35, 30, 33, 28, 37, 31
4.0.1 Creating factors
Following initial cleaning, we identify categorical variables as factors. If you plan to conduct an ANOVA - it’s critical that all predictor variables are converted to factors. Inspect the glimpse() output - if you followed our data entry naming conventions, categorical variables should be of the type character. We have one variable, sex, that is a categorical variable of type character (i.e., chr). The participant id column is categorical as well, but of type double (i.e., dbl) which is a numeric column.
## Rows: 6
## Columns: 5
## $ id <dbl> 1, 2, 3, 4, 5, 6
## $ sex <chr> "male", "female", "male", "female", "male", "female"
## $ march <dbl> 40, 35, 38, 33, 42, 36
## $ may <dbl> 37, 32, 35, 30, 39, 33
## $ july <dbl> 35, 30, 33, 28, 37, 31
You can quickly convert all character columns to factors using the code below. In this case, this just converts the sex column to a factor. Because there is only one column (sex) being converted to a factor, we could have treated it the same was as the id column below. However, we use this code because of its broad applicability to many scripts.
# Turn all columns that are of type character into factors
analytic_data_within <- analytic_data_within %>%
mutate(across(.cols = where(is.character),
.fns = as_factor))
The participant identification number in the id column is a numeric column, so it was not coverted by the above code. The id column is coverted to a factor with the code below.
You can ensure both the sex and id columns are now factors using the glimpse() command.
## Rows: 6
## Columns: 5
## $ id <fct> 1, 2, 3, 4, 5, 6
## $ sex <fct> male, female, male, female, male, female
## $ march <dbl> 40, 35, 38, 33, 42, 36
## $ may <dbl> 37, 32, 35, 30, 39, 33
## $ july <dbl> 35, 30, 33, 28, 37, 31
This example is so small it’s clear you didn’t miss converting any columns to factors. In general, however, at this point you should inspect the output of the glimpse() command and make sure you have coverted all categorical variables to factors - especially those you will use as predictors.
4.0.2 Factor screening
Inspect the levels of each factor carefully. Make sure that there not any levels for a factor that are incorrect. For example, you wouldn’t want to the following levels for sex: male, mmale, female. Obviously, mmale is an incorrectly typed version of male. Scan all the factors in your data for eronious factor levels. The code below displays the factor levels:
## id sex
## 1:1 male :3
## 2:1 female:3
## 3:1
## 4:1
## 5:1
## 6:1
Also inspect the output of the above summary() command paying attention to the order of the levels in the factors. The order influences how graphs are generated. In these data, the sex column has two levels: male and female in that order. Below we adjust the order of the sex varible because we want the x-axis of a future graph to display columns in the left to right order: female, male.
 For example, in the context of this example you want to ensure non of the elapsed_times are impossible or so large they appear to be data entry errors.
One option for doing so is the summary command again. This time, however, we use “is.numeric” in the where() command.
| Name | Piped data |
| Number of rows | 6 |
| Number of columns | 5 |
| _______________________ | |
| Column type frequency: | |
| factor | 2 |
| numeric | 3 |
| ________________________ | |
| Group variables | None |
Variable type: factor
| skim_variable | n_missing | complete_rate | ordered | n_unique | top_counts |
|---|---|---|---|---|---|
| id | 0 | 1 | FALSE | 6 | 1: 1, 2: 1, 3: 1, 4: 1 |
| sex | 0 | 1 | FALSE | 2 | fem: 3, mal: 3 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| march | 0 | 1 | 37.33 | 3.33 | 33 | 35.25 | 37 | 39.5 | 42 | ▃▇▃▃▃ |
| may | 0 | 1 | 34.33 | 3.33 | 30 | 32.25 | 34 | 36.5 | 39 | ▃▇▃▃▃ |
| july | 0 | 1 | 32.33 | 3.33 | 28 | 30.25 | 32 | 34.5 | 37 | ▃▇▃▃▃ |
## skim_variable n_missing mean sd p0 p50 p100
## 1 march 0 37.33 3.33 33 37 42
## 2 may 0 34.33 3.33 30 34 39
## 3 july 0 32.33 3.33 28 32 37
Scan the min and max values for to ensure there are not any impossible values. If necessary, got back to the original data source and fix these impossible value. Alternatively, you might need to change them to missing values (i.e., NA values).
In this example all the values are reasonable values. However, if we discovered an out of range value (or values) for elapsed time we could convert those values to missing values with the code below. This code changes (i.e., mutates) a value in the elapsed_time column to become NA (not available or missing) if that value is less than zero. If the value is greater than or equal to zero, it stays the same. Note that when using this command we have to be very specific in terms of specifying our missing value. It usually needs to be one of NA_real_ or NA_character_. For numeric columns use NA_real_ and for character columns use NA_character_.
4.0.4 Pivot to tidy data
The analytic data in it’s current for does not conform to the the tidy data specification. Inspect the data with the print() command. Notice the there is not column for occasion. The levels of occasion are spread across three columns. Correspondingly, elapsed time is spread across multiple columns in the same row and is not labeled as elaped time. We need to restructure the data into the tidy data format so that we have a single elapsed time observation per row and a single column per variable.
## # A tibble: 6 x 5
## id sex march may july
## <fct> <fct> <dbl> <dbl> <dbl>
## 1 1 male 40 37 35
## 2 2 female 35 32 30
## 3 3 male 38 35 33
## 4 4 female 33 30 28
## 5 5 male 42 39 37
## 6 6 female 36 33 31
The pivot_longer() command below coverts our data to the tidy data format. In this command we specify the the columns march, may, and june are all levels of a single varible called occasion. We specify the columns involved with the cols argument. The code march:july after the cols argument indicates to the computer to use the march column and the july column and all the columns in between. Each column name represents a level of the variable occasion. The names_to argument is used to indicate that a new column called occasion should be created to hold the different months. The value_to argument is used to indicate that a new column called elapsed_time should created to hold all the values from the march, may, and july column.
analytic_data_within_tidy <- analytic_data_within %>%
pivot_longer(cols = march:july,
names_to = "occasion",
values_to = "elapsed_time"
)
You can see the data in the new format below.
## # A tibble: 18 x 4
## id sex occasion elapsed_time
## <fct> <fct> <chr> <dbl>
## 1 1 male march 40
## 2 1 male may 37
## 3 1 male july 35
## 4 2 female march 35
## 5 2 female may 32
## 6 2 female july 30
## 7 3 male march 38
## 8 3 male may 35
## 9 3 male july 33
## 10 4 female march 33
## 11 4 female may 30
## 12 4 female july 28
## 13 5 male march 42
## 14 5 male may 39
## 15 5 male july 37
## 16 6 female march 36
## 17 6 female may 33
## 18 6 female july 31
But notice that the new column occasion is of the type character. We need it to be a factor. So use the code below to do so:
You can confirm that occasion is now a factor with the glimpse() command. Once this is complete, you are done preparing your one-way within participant analytic data.
## Rows: 18
## Columns: 4
## $ id <fct> 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6
## $ sex <fct> male, male, male, female, female, female, male, male, …
## $ occasion <fct> march, may, july, march, may, july, march, may, july, …
## $ elapsed_time <dbl> 40, 37, 35, 35, 32, 30, 38, 35, 33, 33, 30, 28, 42, 39…
You now have two data files… for different things.. Once you are done numeric screening, the data is ready for analysis.
4.1 Experiment: Within N-way
The N-way within-participant ANOVA example uses the data file data_food.csv. Initial loading of the file, including the specification of missing data codes, is provided by the code below. The data corresponds to a designs where the researcher is interested in assessing the taste of food as a function of food type (pizza/steak/burger) and temperature (hot/cold).
# Date: YYYY-MM-DD
# Name: your name here
# Example: Within-participant experiment
# Load data
library(tidyverse)
my_missing_value_codes <- c("-999", "", "NA")
raw_data_within_nway <- read_csv(file = "data_food.csv",
na = my_missing_value_codes)
analytic_data_within_nway <- raw_data_within_nway
After loading the data we do initial cleaning to remove empty row/columns and ensure proper naming for columns:
library(janitor)
# Initial cleaning
analytic_data_within_nway <- analytic_data_within_nway %>%
remove_empty("rows") %>%
remove_empty("cols") %>%
clean_names()
You can confirm the column names following our naming convention with the glimpse command - and see the data type for each column.
## Rows: 6
## Columns: 8
## $ id <dbl> 1, 2, 3, 4, 5, 6
## $ sex <dbl> 1, 2, 1, 2, 1, 2
## $ pizza_hot <dbl> 7, 8, 7, 8, 7, 9
## $ pizza_cold <dbl> 6, 7, 5, 7, 6, 7
## $ steak_hot <dbl> 6, 6, 7, 7, 8, 7
## $ steak_cold <dbl> 3, 3, 4, 5, 7, 8
## $ burger_hot <dbl> 7, 8, 7, 8, 7, 8
## $ burger_cold <dbl> 4, 3, 3, 3, 2, 5
4.1.1 Creating factors
Following initial cleaning, identify categorical variables as factors. If you plan to conduct an ANOVA - it’s critical that all predictor variables are converted to factors. Inspect glimpse() output - if you followed our data entry naming conventions categorical variables should be of the type character. We have one variable sex that is categorical that is of type character (i.e., chr). The participant id column is categorical as well, but of type double (i.e., dbl) which is a numeric column.
## Rows: 6
## Columns: 8
## $ id <dbl> 1, 2, 3, 4, 5, 6
## $ sex <dbl> 1, 2, 1, 2, 1, 2
## $ pizza_hot <dbl> 7, 8, 7, 8, 7, 9
## $ pizza_cold <dbl> 6, 7, 5, 7, 6, 7
## $ steak_hot <dbl> 6, 6, 7, 7, 8, 7
## $ steak_cold <dbl> 3, 3, 4, 5, 7, 8
## $ burger_hot <dbl> 7, 8, 7, 8, 7, 8
## $ burger_cold <dbl> 4, 3, 3, 3, 2, 5
The sex column is a numeric column, so we have handle that column on it’s own.
Now the sex column is a factor but we have to tell the computer that 1 indicates male and 2 indicates female.
analytic_data_within_nway <-analytic_data_within_nway %>%
mutate(sex = fct_recode(sex,
male = "1",
female = "2"))
The participant identification number in the id column is a numeric column, so we have handle that column on it’s own.
You can ensure all of these columns are now factors using the glimpse() command.
## Rows: 6
## Columns: 8
## $ id <fct> 1, 2, 3, 4, 5, 6
## $ sex <fct> male, female, male, female, male, female
## $ pizza_hot <dbl> 7, 8, 7, 8, 7, 9
## $ pizza_cold <dbl> 6, 7, 5, 7, 6, 7
## $ steak_hot <dbl> 6, 6, 7, 7, 8, 7
## $ steak_cold <dbl> 3, 3, 4, 5, 7, 8
## $ burger_hot <dbl> 7, 8, 7, 8, 7, 8
## $ burger_cold <dbl> 4, 3, 3, 3, 2, 5
Inspect the output of the glimpse() command and make sure you have coverted all categorical variables to factors - especially those you will use as predictors.
4.1.2 Factor screening
Inspect the levels of each factor carefully. Make sure that there not any levels present that are incorrect. For example, you wouldn’t want to the following levels for sex: male, mmale, female. Obviously, mmale is an incorrectly typed version of male. Scan all the factor in your data for eronious factor levels. The code below displays the factor levels:
## id sex
## 1:1 male :3
## 2:1 female:3
## 3:1
## 4:1
## 5:1
## 6:1
Also inspect the output of the above summary() command paying attention to the order of the levels in the factors. The order influences how text output and graphs are generated. In these data, the sex column has two levels: male and female in that order. Below we adjust the order of the sex varible because we want the x-axis of a future graph to display columns in the left to right order: female, male.
# Custom reordering of factor levels
analytic_data_within_nway <- analytic_data_within_nway %>%
mutate(sex = fct_relevel(sex,
"female",
"male"))
You can see the new order of the factor levels with summary():
## id sex
## 1:1 female:3
## 2:1 male :3
## 3:1
## 4:1
## 5:1
## 6:1
4.1.3 Numeric screening
For numeric variables, you should search for impossible values.e For example, in the context of this example you want to ensure non of the elapsed_times are impossible or so large they appear to be data entry errors.
One options for doing so is the summary command again. This time, however, we use “is.numeric” in the where() command.
## pizza_hot pizza_cold steak_hot steak_cold burger_hot
## Min. :7.00 Min. :5.00 Min. :6.00 Min. :3.00 Min. :7.0
## 1st Qu.:7.00 1st Qu.:6.00 1st Qu.:6.25 1st Qu.:3.25 1st Qu.:7.0
## Median :7.50 Median :6.50 Median :7.00 Median :4.50 Median :7.5
## Mean :7.67 Mean :6.33 Mean :6.83 Mean :5.00 Mean :7.5
## 3rd Qu.:8.00 3rd Qu.:7.00 3rd Qu.:7.00 3rd Qu.:6.50 3rd Qu.:8.0
## Max. :9.00 Max. :7.00 Max. :8.00 Max. :8.00 Max. :8.0
## burger_cold
## Min. :2.00
## 1st Qu.:3.00
## Median :3.00
## Mean :3.33
## 3rd Qu.:3.75
## Max. :5.00
Scan the min and max values for each variable to ensure there are not any impossible values. If necessary, got back to the original data source and fix these impossible value. Alternatively, you might need to change them to missing values (i.e., NA values). Once this is complete, you are done preparing your between participant analytic data.
4.1.4 Pivot to tidy data
The analytic data in it’s current for does not conform to the the tidy data specification. Inspect the data with the print() command. Notice the there is not column for occasion. The levels of occasion are spread across three columns. Correspondingly, elapsed time is spread across multiple columns in the same row and is not labeled as elaped time. We need to restructure the data into the tidy data format so that we have a single elapsed time observation per row and a single column per variable.
## # A tibble: 6 x 8
## id sex pizza_hot pizza_cold steak_hot steak_cold burger_hot burger_cold
## <fct> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 male 7 6 6 3 7 4
## 2 2 fema… 8 7 6 3 8 3
## 3 3 male 7 5 7 4 7 3
## 4 4 fema… 8 7 7 5 8 3
## 5 5 male 7 6 8 7 7 2
## 6 6 fema… 9 7 7 8 8 5
The pivot_long() command below coverts our data to the tidy data format. In this command we specify the the columns march, may, and june are all levels of a single varible called occasion. We specify the columns involved with the cols argument. The code march:july after the cols argument indicates to the computer to use the march column and the july column and all the columns in between. Each column name represents a level of the variable occasion. The names_to argument is used to indicate that a new column called occasion should be created to hold the different months. The value_to argument is used to indicate that a new column called elapsed_time should created to hold all the values from the march, may, and july column.
analytic_data_nway_tidy <- analytic_data_within_nway %>%
pivot_longer(pizza_hot:burger_cold,
names_to = c("food", "temperature"),
names_sep = "_",
values_to = "taste"
)
You can see the data in the new format below.
## # A tibble: 36 x 5
## id sex food temperature taste
## <fct> <fct> <chr> <chr> <dbl>
## 1 1 male pizza hot 7
## 2 1 male pizza cold 6
## 3 1 male steak hot 6
## 4 1 male steak cold 3
## 5 1 male burger hot 7
## 6 1 male burger cold 4
## 7 2 female pizza hot 8
## 8 2 female pizza cold 7
## 9 2 female steak hot 6
## 10 2 female steak cold 3
## # … with 26 more rows
But notice that the new column occasion is of the type character. We need it to be a factor. So use the code below to do so:
analytic_data_nway_tidy <-analytic_data_nway_tidy %>%
mutate(food = as_factor(food),
temperature = as_factor(temperature))
You can confirm that occasion is now a factor with the glimpse() command. Once this is complete, you are done preparing your one-way within participant analytic data.
## Rows: 36
## Columns: 5
## $ id <fct> 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4…
## $ sex <fct> male, male, male, male, male, male, female, female, fem…
## $ food <fct> pizza, pizza, steak, steak, burger, burger, pizza, pizz…
## $ temperature <fct> hot, cold, hot, cold, hot, cold, hot, cold, hot, cold, …
## $ taste <dbl> 7, 6, 6, 3, 7, 4, 8, 7, 6, 3, 8, 3, 7, 5, 7, 4, 7, 3, 8…
4.2 Surveys: Single Occassion
Even assuming you did everything right there is still a fair amount of work to get things started paragraph here…
We begin by examining the data as originally entered into a spreadsheet. In Figure 4.1 you see a screen shot of the initial raw data as a researcher might receive it. Take careful note of the numerous -999 values used to indicate missing values. As part of creating the analytic data that we will analyze we need to indicate to the computer that the -999 are not data but codes to represent missing values.
- Create a new script in your project and save it with the name “script_raw_to_analytic.R”
- Type the code below into that script
# Date: YYYY-MM-DD
# Name: your name here
# Example: single occasion survey
# Load data
library(tidyverse)
my_missing_value_codes <- c("-999", "", "NA")
raw_data_survey <- read_csv(file = "data_item_scoring.csv",
na = my_missing_value_codes)
## Parsed with column specification:
## cols(
## id = col_double(),
## age = col_double(),
## sex = col_character(),
## eye_color = col_character(),
## esteem1 = col_double(),
## esteem2 = col_double(),
## esteem3 = col_double(),
## esteem4 = col_double(),
## esteem5_rev15 = col_double(),
## jobsat1 = col_double(),
## jobsat2_rev15 = col_double(),
## jobsat3 = col_double(),
## jobsat4 = col_double(),
## jobsat5 = col_double()
## )
Remove empty row and columns from your data using the remove_empty_cols() and remove_empty_rows(), respectively. As well, clean the names of your columns to ensure they conform to tidyverse naming conventions.
library(janitor)
# Initial cleaning
analytic_data_survey <- analytic_data_survey %>%
remove_empty("rows") %>%
remove_empty("cols") %>%
clean_names()
You can confirm the column names following our naming convention with the glimpse command - and see the data type for each column.
## Rows: 300
## Columns: 14
## $ id <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16…
## $ age <dbl> 23, 22, 18, 23, 22, 17, 23, 22, 17, NA, 20, 17, 24, 1…
## $ sex <chr> "male", "female", "male", "female", "male", "female",…
## $ eye_color <chr> "blue", "brown", "hazel", "blue", NA, "hazel", "blue"…
## $ esteem1 <dbl> 3, 4, 4, 3, 3, 3, 3, 4, 4, 4, 3, 4, NA, NA, 3, 3, 3, …
## $ esteem2 <dbl> 2, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2, 2, NA, 3, 2, 2, 2, 2…
## $ esteem3 <dbl> 4, 4, 4, 3, 4, 4, NA, 4, 4, 3, 4, 4, 4, NA, 4, NA, NA…
## $ esteem4 <dbl> 3, 4, 4, 3, 4, 4, 4, 4, 3, 4, NA, 4, 3, 3, 4, NA, 3, …
## $ esteem5_rev15 <dbl> 2, 2, 2, 2, 2, NA, NA, 2, 2, 2, 3, 2, 2, 3, 3, NA, 3,…
## $ jobsat1 <dbl> 3, 5, 4, 3, 3, 3, 3, 5, 3, 3, 3, 4, 4, 3, 3, 4, 3, 3,…
## $ jobsat2_rev15 <dbl> 1, 1, 1, NA, 1, 1, 2, 1, 2, 2, 3, 1, 3, 2, 1, 1, 2, 3…
## $ jobsat3 <dbl> 3, NA, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 2…
## $ jobsat4 <dbl> NA, 5, 5, 4, 4, 4, 4, 5, NA, 4, NA, 5, 4, 4, 4, 5, 4,…
## $ jobsat5 <dbl> 5, NA, 5, 4, 5, 4, 4, 5, 5, 5, 4, NA, 4, 5, 4, 4, 4, …
4.2.1 Creating factors
Following initial cleaning, identify categorical variables as factors. If you plan to conduct an ANOVA - it’s critical that all predictor variables are converted to factors. Inspect glimpse() output - if you followed our data entry naming conventions categorical variables should be of the type character
## Rows: 300
## Columns: 14
## $ id <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16…
## $ age <dbl> 23, 22, 18, 23, 22, 17, 23, 22, 17, NA, 20, 17, 24, 1…
## $ sex <chr> "male", "female", "male", "female", "male", "female",…
## $ eye_color <chr> "blue", "brown", "hazel", "blue", NA, "hazel", "blue"…
## $ esteem1 <dbl> 3, 4, 4, 3, 3, 3, 3, 4, 4, 4, 3, 4, NA, NA, 3, 3, 3, …
## $ esteem2 <dbl> 2, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2, 2, NA, 3, 2, 2, 2, 2…
## $ esteem3 <dbl> 4, 4, 4, 3, 4, 4, NA, 4, 4, 3, 4, 4, 4, NA, 4, NA, NA…
## $ esteem4 <dbl> 3, 4, 4, 3, 4, 4, 4, 4, 3, 4, NA, 4, 3, 3, 4, NA, 3, …
## $ esteem5_rev15 <dbl> 2, 2, 2, 2, 2, NA, NA, 2, 2, 2, 3, 2, 2, 3, 3, NA, 3,…
## $ jobsat1 <dbl> 3, 5, 4, 3, 3, 3, 3, 5, 3, 3, 3, 4, 4, 3, 3, 4, 3, 3,…
## $ jobsat2_rev15 <dbl> 1, 1, 1, NA, 1, 1, 2, 1, 2, 2, 3, 1, 3, 2, 1, 1, 2, 3…
## $ jobsat3 <dbl> 3, NA, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 2…
## $ jobsat4 <dbl> NA, 5, 5, 4, 4, 4, 4, 5, NA, 4, NA, 5, 4, 4, 4, 5, 4,…
## $ jobsat5 <dbl> 5, NA, 5, 4, 5, 4, 4, 5, 5, 5, 4, NA, 4, 5, 4, 4, 4, …
You can quickly convert all character columns to factors using the code below:
# Turn all columns that are of type character into factors
analytic_data_survey <- analytic_data_survey %>%
mutate(across(.cols = where(is.character),
.fns = as_factor))
The participant identification number in the id column is a numeric column, so we have handle that column on it’s own.
You can ensure all of these columns are now factors using the glimpse() command.
## Rows: 300
## Columns: 14
## $ id <fct> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16…
## $ age <dbl> 23, 22, 18, 23, 22, 17, 23, 22, 17, NA, 20, 17, 24, 1…
## $ sex <fct> male, female, male, female, male, female, male, femal…
## $ eye_color <fct> blue, brown, hazel, blue, NA, hazel, blue, brown, haz…
## $ esteem1 <dbl> 3, 4, 4, 3, 3, 3, 3, 4, 4, 4, 3, 4, NA, NA, 3, 3, 3, …
## $ esteem2 <dbl> 2, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2, 2, NA, 3, 2, 2, 2, 2…
## $ esteem3 <dbl> 4, 4, 4, 3, 4, 4, NA, 4, 4, 3, 4, 4, 4, NA, 4, NA, NA…
## $ esteem4 <dbl> 3, 4, 4, 3, 4, 4, 4, 4, 3, 4, NA, 4, 3, 3, 4, NA, 3, …
## $ esteem5_rev15 <dbl> 2, 2, 2, 2, 2, NA, NA, 2, 2, 2, 3, 2, 2, 3, 3, NA, 3,…
## $ jobsat1 <dbl> 3, 5, 4, 3, 3, 3, 3, 5, 3, 3, 3, 4, 4, 3, 3, 4, 3, 3,…
## $ jobsat2_rev15 <dbl> 1, 1, 1, NA, 1, 1, 2, 1, 2, 2, 3, 1, 3, 2, 1, 1, 2, 3…
## $ jobsat3 <dbl> 3, NA, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 2…
## $ jobsat4 <dbl> NA, 5, 5, 4, 4, 4, 4, 5, NA, 4, NA, 5, 4, 4, 4, 5, 4,…
## $ jobsat5 <dbl> 5, NA, 5, 4, 5, 4, 4, 5, 5, 5, 4, NA, 4, 5, 4, 4, 4, …
Inspect the output of the glimpse() command and make sure you have coverted all categorical variables to factors - especially those you will use as predictors.
4.2.2 Factor screening
Inspect the levels of each factor carefully. Make sure that there not any levels present that are incorrect. For example, you wouldn’t want to the following levels for sex: male, mmale, female. Obviously, mmale is an incorrectly typed version of male. Scan all the factor in your data for eronious factor levels. The code below displays the factor levels:
## id sex eye_color
## 1 : 1 male :147 blue : 99
## 2 : 1 female :149 brown: 98
## 3 : 1 intersex: 2 hazel:100
## 4 : 1 NA's : 2 NA's : 3
## 5 : 1
## 6 : 1
## (Other):294
Also inspect the output of the above summary() command paying attention to the order of the levels in the factors. The order influences how text output and graphs are generated. In these data, the sex column has two levels: male and female in that order. Below we adjust the order of the sex varible because we want the x-axis of a future graph to display columns in the left to right order: female, male.
# Custom reordering of factor levels
analytic_data_survey <- analytic_data_survey %>%
mutate(sex = fct_relevel(sex,
"intersex",
"female",
"male"))
For eye color, we want to future graph to be have the most commmon eye colors on the left so we reorder the factor levels:
# Reordering factor levels by frequency
analytic_data_survey <- analytic_data_survey %>%
mutate(eye_color = fct_infreq(eye_color))
You can see the new order of the factor levels with summary():
## id sex eye_color
## 1 : 1 intersex: 2 hazel:100
## 2 : 1 female :149 blue : 99
## 3 : 1 male :147 brown: 98
## 4 : 1 NA's : 2 NA's : 3
## 5 : 1
## 6 : 1
## (Other):294
4.2.3 Numeric screening
For numeric variables, you should search for impossible values. For example, in the context of this example you want to ensure none of the elapsed_times are impossible or so large they appear to be data entry errors.
One options for doing so is the summary command again. This time, however, we use “is.numeric” in the where() command. However, when a survey has a large number of variables this type of output can become challenging to intrepret.
With larger numers of variables, it’s a good idea to use the skimr package. Additionally, it makes sense to look at sets of items rather than all of the variables at once. This is because sometime items and different response formats. For example, for one measure this responses may range from 1 to 5 whereas for another measure responses could range from 1 to 7. This is undesirable from a psychometric point of view, as discussed previously, but it if happens it makes sense to look at items in sets.
Start by examining the range of non-scale items. In this case it’s only age. Examine the output to see if any of the age values are unreasonble. In the output p0 and p100 indicate the 0th percentile and the 100th percentile; that is the min an max values for the variable. Check to make sure none of the age values are unreasonably low or high. If they are, you may need to check the original data source or replace them with missing values.
## skim_variable n_missing mean sd p0 p50 p100
## 1 age 3 20.52 2.05 17 20 24
Look the items in the first scale, self-esteem. Possible items responses for this scale range from 1 to 5, make sure they are all in this range. In the output p0 and p100 indicate the 0th percentile and the 100th percentile; that is the minimum an maximum values for the variable in these data. Examine the output to see if any of the esteem values are unreasonble (i.e., fall outside the 1 to 5 range). If any values fall outside this range, you may need to check the original data source or replace them with missing values - as described previously.
## skim_variable n_missing mean sd p0 p50 p100
## 1 esteem1 24 3.39 0.54 3 3 5
## 2 esteem2 28 2.35 0.48 2 2 3
## 3 esteem3 31 3.96 0.37 3 4 5
## 4 esteem4 15 3.54 0.50 3 4 4
## 5 esteem5_rev15 35 2.22 0.47 1 2 3
Follow the same process for the job satisfaction items. Possible items responses for this scale range from 1 to 5, make sure they are all in this range. If any values fall outside this range, you may need to check the original data source or replace them with missing values - as described previously.
## skim_variable n_missing mean sd p0 p50 p100
## 1 jobsat1 25 3.34 0.51 3 3 5
## 2 jobsat2_rev15 27 1.51 0.61 1 1 3
## 3 jobsat3 28 2.84 0.37 2 3 3
## 4 jobsat4 35 4.29 0.70 3 4 5
## 5 jobsat5 24 4.57 0.61 3 5 5
4.2.4 Scale scores
Scale scores involve averaging, for each person, their score over several items to create an overall scale score. The first step in the creation of scales if correcting the values of any reverse-keyed items, as described previously.
<IP_ADDRESS> Reverse key items
The way you deal with reverse-keyed items depends on how you scored them. Imagine you had a 5-point scale. You could have scored the scale with the values 1, 2, 3, 4, and 5. Alternatively, you could have scored the scale with the values 0, 1, 2, 3, and 4. In this example, we scored the data using the 1 to 5 system. So we’ll use that. Later I’ll show you how to deal with the other scoring system (0 to 4).
We need to take items that were reversed-key when the participant wrote them and recode those responses. We do that with using the mutate command.
In this data file all the reverse-keyed were identified with the suffix "_rev15" in the column names. This suffix indicates the item was reverse-keyed and that the original scale used the response points 1 to 5. We can see those items with the glimpse() command below. Notice that there are two reverse keyed items - both on difference scales.
## Rows: 300
## Columns: 2
## $ esteem5_rev15 <dbl> 2, 2, 2, 2, 2, NA, NA, 2, 2, 2, 3, 2, 2, 3, 3, NA, 3,…
## $ jobsat2_rev15 <dbl> 1, 1, 1, NA, 1, 1, 2, 1, 2, 2, 3, 1, 3, 2, 1, 1, 2, 3…
To correct a reverse-keyed items that ranges where the lowest possible rating value is a 1 (i.e, 1 on a 1 to 5 scale), we simply subtract all the scores from one more than the highest possible rating. For example, if a 1 to 5 response scale was used we subtract each response from 6 to obaiin the recoded value.
| Original value | Math | Recoded value |
|---|---|---|
| 1 | 6 - 1 | 5 |
| 2 | 6 - 2 | 4 |
| 3 | 6 - 3 | 3 |
| 4 | 6 - 4 | 2 |
| 5 | 6 - 5 | 1 |
The code below: * selects each column that ends with "_rev15" (i.e., both esteem and jobsat scales) * subtracts each value in that column from 6 * renames the column by removing "_rev15" because the reverse coding is complete.
analytic_data_survey <- analytic_data_survey %>%
mutate(6 - across(.cols = ends_with("_rev15")) ) %>%
rename_with(.fn = str_remove,
.cols = ends_with("_rev15"),
pattern = "_rev15")
You can use the glimpse() command to see the result of your work. If you compare this to values from the previous glimpse() command you can see they have changed. Also notice the column names not longer indicate the items are reverse-keyed.
## Rows: 300
## Columns: 14
## $ id <fct> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17…
## $ age <dbl> 23, 22, 18, 23, 22, 17, 23, 22, 17, NA, 20, 17, 24, 17, N…
## $ sex <fct> male, female, male, female, male, female, male, female, m…
## $ eye_color <fct> blue, brown, hazel, blue, NA, hazel, blue, brown, hazel, …
## $ esteem1 <dbl> 3, 4, 4, 3, 3, 3, 3, 4, 4, 4, 3, 4, NA, NA, 3, 3, 3, 3, 3…
## $ esteem2 <dbl> 2, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2, 2, NA, 3, 2, 2, 2, 2, 3,…
## $ esteem3 <dbl> 4, 4, 4, 3, 4, 4, NA, 4, 4, 3, 4, 4, 4, NA, 4, NA, NA, 3,…
## $ esteem4 <dbl> 3, 4, 4, 3, 4, 4, 4, 4, 3, 4, NA, 4, 3, 3, 4, NA, 3, 3, 4…
## $ esteem5 <dbl> 4, 4, 4, 4, 4, NA, NA, 4, 4, 4, 3, 4, 4, 3, 3, NA, 3, 3, …
## $ jobsat1 <dbl> 3, 5, 4, 3, 3, 3, 3, 5, 3, 3, 3, 4, 4, 3, 3, 4, 3, 3, 3, …
## $ jobsat2 <dbl> 5, 5, 5, NA, 5, 5, 4, 5, 4, 4, 3, 5, 3, 4, 5, 5, 4, 3, 5,…
## $ jobsat3 <dbl> 3, NA, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 3,…
## $ jobsat4 <dbl> NA, 5, 5, 4, 4, 4, 4, 5, NA, 4, NA, 5, 4, 4, 4, 5, 4, 3, …
## $ jobsat5 <dbl> 5, NA, 5, 4, 5, 4, 4, 5, 5, 5, 4, NA, 4, 5, 4, 4, 4, 4, 5…
If your scale had used response options numbered 0 to 4 the math is different. For each item you would use subtract values from the highest possible point (i.e, 4) instead of one larger than the highest possible point.
| Original value | Math | Recoded value |
|---|---|---|
| 0 | 4 - 0 | 4 |
| 1 | 4 - 1 | 3 |
| 2 | 4 - 2 | 2 |
| 3 | 4 - 3 | 1 |
| 4 | 4 - 4 | 0 |
Thus the mutate command would instead be:
mutate(4 - across(.cols = ends_with("_rev15")) )<IP_ADDRESS> Creating scores
The process we use for creating scale scores deletes item level data from analytic_data_survey. This is a desirable aspect of the process we it removes information we are no longer interested in from our analytic data. That said, before we create scale score, we create a backup on the item level data called analytic_data_items. We will need to use this backup later to compute the reliability of the scales we are creating.
We want to make a self_esteem scale and plan to select items using starts_with(“esteem”). But prior to doing this we make sure the start_with() command only gives us the items we want - and not additional unwanted items. The output below confirms there are not problems associated with using starts_with(“esteem”).
# confirm select will select the columns you want (and not others)
analytic_data_survey %>%
select(starts_with("esteem")) %>%
glimpse()
## Rows: 300
## Columns: 5
## $ esteem1 <dbl> 3, 4, 4, 3, 3, 3, 3, 4, 4, 4, 3, 4, NA, NA, 3, 3, 3, 3, 3, …
## $ esteem2 <dbl> 2, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2, 2, NA, 3, 2, 2, 2, 2, 3, 2…
## $ esteem3 <dbl> 4, 4, 4, 3, 4, 4, NA, 4, 4, 3, 4, 4, 4, NA, 4, NA, NA, 3, 4…
## $ esteem4 <dbl> 3, 4, 4, 3, 4, 4, 4, 4, 3, 4, NA, 4, 3, 3, 4, NA, 3, 3, 4, …
## $ esteem5 <dbl> 4, 4, 4, 4, 4, NA, NA, 4, 4, 4, 3, 4, 4, 3, 3, NA, 3, 3, NA…
Likewise, we want to make a job_sat scale and plan to select items using starts_with(“jobsat”). The code and output below using starts_with(“jobsat”) only returns the items we are interested in.
# confirm select will select the columns you want (and not others)
analytic_data_survey %>%
select(starts_with("jobsat")) %>%
glimpse()
## Rows: 300
## Columns: 5
## $ jobsat1 <dbl> 3, 5, 4, 3, 3, 3, 3, 5, 3, 3, 3, 4, 4, 3, 3, 4, 3, 3, 3, 3,…
## $ jobsat2 <dbl> 5, 5, 5, NA, 5, 5, 4, 5, 4, 4, 3, 5, 3, 4, 5, 5, 4, 3, 5, 4…
## $ jobsat3 <dbl> 3, NA, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 3, 3…
## $ jobsat4 <dbl> NA, 5, 5, 4, 4, 4, 4, 5, NA, 4, NA, 5, 4, 4, 4, 5, 4, 3, 4,…
## $ jobsat5 <dbl> 5, NA, 5, 4, 5, 4, 4, 5, 5, 5, 4, NA, 4, 5, 4, 4, 4, 4, 5, …
We computer the scale scores using the rowwise() command. The mean() command provides the mean of columns by default - not people. We use the rowwise() command in the code below to that the mean() command will work across columns rather than within columns. The mutate comand calculates the scale score for each person. The c_across() command combined with the starts_with() command ensure the items we want averaged together are the items that are averaged together. Notice there is a separate mutate line for each scale. The ungroup() command turns off the rowwise() command. We end the code block by remove the item-level data from the data set.
analytic_data_survey <- analytic_data_survey %>%
rowwise() %>%
mutate(self_esteem = mean(c_across(starts_with("esteem")),
na.rm = TRUE)) %>%
mutate(job_sat = mean(c_across(starts_with("jobsat")),
na.rm = TRUE)) %>%
ungroup() %>%
select(-starts_with("esteem")) %>%
select(-starts_with("jobsat"))
We can see our data now has the self esteem column, a job_sat column, and that all of the item level data has been removed.
## Rows: 300
## Columns: 6
## $ id <fct> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, …
## $ age <dbl> 23, 22, 18, 23, 22, 17, 23, 22, 17, NA, 20, 17, 24, 17,…
## $ sex <fct> male, female, male, female, male, female, male, female,…
## $ eye_color <fct> blue, brown, hazel, blue, NA, hazel, blue, brown, hazel…
## $ self_esteem <dbl> 3.200, 3.800, 3.800, 3.000, 3.400, 3.500, 3.000, 3.800,…
## $ job_sat <dbl> 4.000, 5.000, 4.400, 3.500, 4.000, 3.800, 3.600, 4.600,…
These data are ready for analysis.
4.3 Surveys: Multiple Occasions
library(tidyverse)
raw_data_occasions <- read_csv("data_item_time.csv")
analytic_data_occasions <- raw_data_occasions
## Rows: 300
## Columns: 24
## $ id <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,…
## $ age <dbl> 23, 22, 18, 23, 22, 17, 23, 22, 17, NA, 20, 17, 24…
## $ sex <chr> "male", "female", "male", "female", "male", "femal…
## $ eye_color <chr> "blue", "brown", "hazel", "blue", NA, "hazel", "bl…
## $ t1_esteem1 <dbl> 3, 4, 4, 3, 3, 3, 3, 4, 4, 4, 3, 4, NA, NA, 3, 3, …
## $ t1_esteem2 <dbl> 2, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2, 2, NA, 3, 2, 2, 2…
## $ t1_esteem3 <dbl> 4, 4, 4, 3, 4, 4, NA, 4, 4, 3, 4, 4, 4, NA, 4, NA,…
## $ t1_esteem4 <dbl> 3, 4, 4, 3, 4, 4, 4, 4, 3, 4, NA, 4, 3, 3, 4, NA, …
## $ t1_esteem5_rev15 <dbl> 2, 2, 2, 2, 2, NA, NA, 2, 2, 2, 3, 2, 2, 3, 3, NA,…
## $ t1_jobsat1 <dbl> 3, 5, 4, 3, 3, 3, 3, 5, 3, 3, 3, 4, 4, 3, 3, 4, 3,…
## $ t1_jobsat2_rev15 <dbl> 1, 1, 1, NA, 1, 1, 2, 1, 2, 2, 3, 1, 3, 2, 1, 1, 2…
## $ t1_jobsat3 <dbl> 3, NA, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2…
## $ t1_jobsat4 <dbl> NA, 5, 5, 4, 4, 4, 4, 5, NA, 4, NA, 5, 4, 4, 4, 5,…
## $ t1_jobsat5 <dbl> 5, NA, 5, 4, 5, 4, 4, 5, 5, 5, 4, NA, 4, 5, 4, 4, …
## $ t2_esteem1 <dbl> 4, 5, 5, 4, NA, 4, 4, 5, 5, 5, 4, 5, 3, 3, 4, 4, 4…
## $ t2_esteem2 <dbl> 3, 4, 4, 3, 3, 4, 3, 4, 4, 4, 3, 3, 3, 4, 3, 3, 3,…
## $ t2_esteem3 <dbl> 5, 5, 5, 4, 5, 5, 3, 5, 5, 4, 5, NA, 5, 3, 5, 3, 3…
## $ t2_esteem4 <dbl> 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 3, 5, 4, 4, 5, 3, 4,…
## $ t2_esteem5_rev15 <dbl> 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 4, 4, 3, 4,…
## $ t2_jobsat1 <dbl> 4, 6, 5, 4, 4, 4, 4, 6, 4, NA, 4, 5, 5, 4, 4, 5, 4…
## $ t2_jobsat2_rev15 <dbl> 2, 2, 2, 3, 2, 2, 3, 2, 3, 3, 4, 2, 4, 3, 2, 2, 3,…
## $ t2_jobsat3 <dbl> 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 3,…
## $ t2_jobsat4 <dbl> 3, 6, 6, 5, 5, 5, 5, 6, 3, 5, 3, 6, 5, 5, 5, 6, 5,…
## $ t2_jobsat5 <dbl> 6, 3, 6, 5, NA, 5, 5, 6, 6, 6, 5, 3, 5, 6, 5, 5, 5…
4.3.1 Creating factors
Following initial cleaning, identify categorical variables as factors. If you plan to conduct an ANOVA - it’s critical that all predictor variables are converted to factors. Inspect glimpse() output - if you followed our data entry naming conventions categorical variables should be of the type character
## Rows: 300
## Columns: 24
## $ id <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,…
## $ age <dbl> 23, 22, 18, 23, 22, 17, 23, 22, 17, NA, 20, 17, 24…
## $ sex <chr> "male", "female", "male", "female", "male", "femal…
## $ eye_color <chr> "blue", "brown", "hazel", "blue", NA, "hazel", "bl…
## $ t1_esteem1 <dbl> 3, 4, 4, 3, 3, 3, 3, 4, 4, 4, 3, 4, NA, NA, 3, 3, …
## $ t1_esteem2 <dbl> 2, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2, 2, NA, 3, 2, 2, 2…
## $ t1_esteem3 <dbl> 4, 4, 4, 3, 4, 4, NA, 4, 4, 3, 4, 4, 4, NA, 4, NA,…
## $ t1_esteem4 <dbl> 3, 4, 4, 3, 4, 4, 4, 4, 3, 4, NA, 4, 3, 3, 4, NA, …
## $ t1_esteem5_rev15 <dbl> 2, 2, 2, 2, 2, NA, NA, 2, 2, 2, 3, 2, 2, 3, 3, NA,…
## $ t1_jobsat1 <dbl> 3, 5, 4, 3, 3, 3, 3, 5, 3, 3, 3, 4, 4, 3, 3, 4, 3,…
## $ t1_jobsat2_rev15 <dbl> 1, 1, 1, NA, 1, 1, 2, 1, 2, 2, 3, 1, 3, 2, 1, 1, 2…
## $ t1_jobsat3 <dbl> 3, NA, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2…
## $ t1_jobsat4 <dbl> NA, 5, 5, 4, 4, 4, 4, 5, NA, 4, NA, 5, 4, 4, 4, 5,…
## $ t1_jobsat5 <dbl> 5, NA, 5, 4, 5, 4, 4, 5, 5, 5, 4, NA, 4, 5, 4, 4, …
## $ t2_esteem1 <dbl> 4, 5, 5, 4, NA, 4, 4, 5, 5, 5, 4, 5, 3, 3, 4, 4, 4…
## $ t2_esteem2 <dbl> 3, 4, 4, 3, 3, 4, 3, 4, 4, 4, 3, 3, 3, 4, 3, 3, 3,…
## $ t2_esteem3 <dbl> 5, 5, 5, 4, 5, 5, 3, 5, 5, 4, 5, NA, 5, 3, 5, 3, 3…
## $ t2_esteem4 <dbl> 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 3, 5, 4, 4, 5, 3, 4,…
## $ t2_esteem5_rev15 <dbl> 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 4, 4, 3, 4,…
## $ t2_jobsat1 <dbl> 4, 6, 5, 4, 4, 4, 4, 6, 4, NA, 4, 5, 5, 4, 4, 5, 4…
## $ t2_jobsat2_rev15 <dbl> 2, 2, 2, 3, 2, 2, 3, 2, 3, 3, 4, 2, 4, 3, 2, 2, 3,…
## $ t2_jobsat3 <dbl> 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 3,…
## $ t2_jobsat4 <dbl> 3, 6, 6, 5, 5, 5, 5, 6, 3, 5, 3, 6, 5, 5, 5, 6, 5,…
## $ t2_jobsat5 <dbl> 6, 3, 6, 5, NA, 5, 5, 6, 6, 6, 5, 3, 5, 6, 5, 5, 5…
You can quickly convert all character columns to factors using the code below. In this case, that will convert the sex and eye_colour columns to factors.
analytic_data_occasions <- analytic_data_occasions %>%
mutate(across(.cols = where(is.character),
.fns = as_factor))
The participant identification number in the id column is a numeric column, so we have handle that column on it’s own.
You can ensure all of these columns are now factors using the glimpse() command.
## Rows: 300
## Columns: 24
## $ id <fct> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,…
## $ age <dbl> 23, 22, 18, 23, 22, 17, 23, 22, 17, NA, 20, 17, 24…
## $ sex <fct> male, female, male, female, male, female, male, fe…
## $ eye_color <fct> blue, brown, hazel, blue, NA, hazel, blue, brown, …
## $ t1_esteem1 <dbl> 3, 4, 4, 3, 3, 3, 3, 4, 4, 4, 3, 4, NA, NA, 3, 3, …
## $ t1_esteem2 <dbl> 2, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2, 2, NA, 3, 2, 2, 2…
## $ t1_esteem3 <dbl> 4, 4, 4, 3, 4, 4, NA, 4, 4, 3, 4, 4, 4, NA, 4, NA,…
## $ t1_esteem4 <dbl> 3, 4, 4, 3, 4, 4, 4, 4, 3, 4, NA, 4, 3, 3, 4, NA, …
## $ t1_esteem5_rev15 <dbl> 2, 2, 2, 2, 2, NA, NA, 2, 2, 2, 3, 2, 2, 3, 3, NA,…
## $ t1_jobsat1 <dbl> 3, 5, 4, 3, 3, 3, 3, 5, 3, 3, 3, 4, 4, 3, 3, 4, 3,…
## $ t1_jobsat2_rev15 <dbl> 1, 1, 1, NA, 1, 1, 2, 1, 2, 2, 3, 1, 3, 2, 1, 1, 2…
## $ t1_jobsat3 <dbl> 3, NA, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2…
## $ t1_jobsat4 <dbl> NA, 5, 5, 4, 4, 4, 4, 5, NA, 4, NA, 5, 4, 4, 4, 5,…
## $ t1_jobsat5 <dbl> 5, NA, 5, 4, 5, 4, 4, 5, 5, 5, 4, NA, 4, 5, 4, 4, …
## $ t2_esteem1 <dbl> 4, 5, 5, 4, NA, 4, 4, 5, 5, 5, 4, 5, 3, 3, 4, 4, 4…
## $ t2_esteem2 <dbl> 3, 4, 4, 3, 3, 4, 3, 4, 4, 4, 3, 3, 3, 4, 3, 3, 3,…
## $ t2_esteem3 <dbl> 5, 5, 5, 4, 5, 5, 3, 5, 5, 4, 5, NA, 5, 3, 5, 3, 3…
## $ t2_esteem4 <dbl> 4, 5, 5, 4, 5, 5, 5, 5, 4, 5, 3, 5, 4, 4, 5, 3, 4,…
## $ t2_esteem5_rev15 <dbl> 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 4, 4, 3, 4,…
## $ t2_jobsat1 <dbl> 4, 6, 5, 4, 4, 4, 4, 6, 4, NA, 4, 5, 5, 4, 4, 5, 4…
## $ t2_jobsat2_rev15 <dbl> 2, 2, 2, 3, 2, 2, 3, 2, 3, 3, 4, 2, 4, 3, 2, 2, 3,…
## $ t2_jobsat3 <dbl> 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 3,…
## $ t2_jobsat4 <dbl> 3, 6, 6, 5, 5, 5, 5, 6, 3, 5, 3, 6, 5, 5, 5, 6, 5,…
## $ t2_jobsat5 <dbl> 6, 3, 6, 5, NA, 5, 5, 6, 6, 6, 5, 3, 5, 6, 5, 5, 5…
Inspect the output of the glimpse() command and make sure you have coverted all categorical variables to factors - especially those you will use as predictors.
4.3.2 Screening factors
Inspect the levels of each factor carefully. Make sure that there not any levels present that are incorrect. For example, you wouldn’t want to the following levels for sex: male, mmale, female. Obviously, mmale is an incorrectly typed version of male. Scan all the factor in your data for eronious factor levels. The code below displays the factor levels:
## id sex eye_color
## 1 : 1 male :147 blue : 99
## 2 : 1 female :149 brown: 98
## 3 : 1 intersex: 2 hazel:100
## 4 : 1 NA's : 2 NA's : 3
## 5 : 1
## 6 : 1
## (Other):294
Also inspect the output of the above summary() command paying attention to the order of the levels in the factors. The order influences how text output and graphs are generated. In these data, the sex column has two levels: male and female in that order. Below we adjust the order of the sex varible because we want the x-axis of a future graph to display columns in the left to right order: female, male.
# Custom reordering of factor levels for sex
analytic_data_occasions <- analytic_data_occasions %>%
mutate(sex = fct_relevel(sex,
"intersex",
"female",
"male"))
For eye color, we want to future graph to be have the most commmon eye colors on the left so we reorder the factor levels:
# Reordering factor levels by frequency
analytic_data_occasions <- analytic_data_occasions %>%
mutate(eye_color = fct_infreq(eye_color))
You can see the new order of the factor levels with summary():
## id sex eye_color
## 1 : 1 intersex: 2 hazel:100
## 2 : 1 female :149 blue : 99
## 3 : 1 male :147 brown: 98
## 4 : 1 NA's : 2 NA's : 3
## 5 : 1
## 6 : 1
## (Other):294
4.3.3 Numeric screening
For numeric variables, you should search for impossible values. For example, in the context of this example you want to ensure none of the elapsed_times are impossible or so large they appear to be data entry errors.
One options for doing so is the summary command again. This time, however, we use “is.numeric” in the where() command. However, when a survey has a large number of variables this type of output can become challenging to intrepret.
With larger numers of variables, it’s a good idea to use the skimr package. Additionally, it makes sense to look at sets of items rather than all of the variables at once. This is because sometime items and different response formats. For example, for one measure this responses may range from 1 to 5 whereas for another measure responses could range from 1 to 7. This is undesirable from a psychometric point of view, as discussed previously, but it if happens it makes sense to look at items in sets.
Start by examining the range of non-scale items. In this case it’s only age. Examine the output to see if any of the age values are unreasonble. In the output p0 and p100 indicate the 0th percentile and the 100th percentile; that is the min an max values for the variable. Check to make sure none of the age values are unreasonably low or high. If they are, you may need to check the original data source or replace them with missing values.
## skim_variable n_missing mean sd p0 p50 p100
## 1 age 3 20.52 2.05 17 20 24
Look the items in the first scale, self-esteem. Possible items responses for this scale range from 1 to 5, make sure they are all in this range. In the output p0 and p100 indicate the 0th percentile and the 100th percentile; that is the minimum an maximum values for the variable in these data. Examine the output to see if any of the esteem values are unreasonble (i.e., fall outside the 1 to 5 range). If any values fall outside this range, you may need to check the original data source or replace them with missing values - as described previously.
## skim_variable n_missing mean sd p0 p50 p100
## 1 t1_esteem1 24 3.39 0.54 3 3 5
## 2 t1_esteem2 28 2.35 0.48 2 2 3
## 3 t1_esteem3 31 3.96 0.37 3 4 5
## 4 t1_esteem4 15 3.54 0.50 3 4 4
## 5 t1_esteem5_rev15 35 2.22 0.47 1 2 3
Follow the same process t2_esteem items, t1_jobsat items, and t2_jobsat items. Possible items responses for these scale ranges from 1 to 5, make sure all responses are all in this range. If any values fall outside this range, you may need to check the original data source or replace them with missing values - as described previously.
4.3.4 Scale scores
<IP_ADDRESS> Reverse key items
Scale scores involve averaging, for each person, their score over several items to create an overall scale score. The first step in the creation of scales if correcting the values of any reverse-keyed items, as described previously. The logic of the math behind this correction is described previously in Surveys: Single occasion.
In these data, the items use a 1 to 5 response scale so we use the reverse item correction for response scales that beging with 1. See Surveys: Single occasion for how to handle a response format that begins with zero - the math is different.
The code below: * selects each column that ends with "_rev15" (i.e., both esteem and jobsat scales) * subtracts each value in that column from 6 * renames the column by removing "_rev15" because the reverse coding is complete.
<IP_ADDRESS> Creating scores
The process we use for creating scale scores deletes item level data from analytic_data_survey. This is a desirable aspect of the process we it removes information we are no longer interested in from our analytic data. That said, before we create scale score, we create a backup on the item level data called analytic_data_items. We will need to use this backup later to compute the reliability of the scales we are creating.
We want to make a self_esteem scale and plan to select items using starts_with(“esteem”). But prior to doing this we make sure the start_with() command only gives us the items we want - and not additional unwanted items. The output below confirms there are not problems associated with using starts_with(“esteem”).
## Rows: 300
## Columns: 5
## $ t1_esteem1 <dbl> 3, 4, 4, 3, 3, 3, 3, 4, 4, 4, 3, 4, NA, NA, 3, 3, 3, 3, …
## $ t1_esteem2 <dbl> 2, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2, 2, NA, 3, 2, 2, 2, 2, 3…
## $ t1_esteem3 <dbl> 4, 4, 4, 3, 4, 4, NA, 4, 4, 3, 4, 4, 4, NA, 4, NA, NA, 3…
## $ t1_esteem4 <dbl> 3, 4, 4, 3, 4, 4, 4, 4, 3, 4, NA, 4, 3, 3, 4, NA, 3, 3, …
## $ t1_esteem5 <dbl> 4, 4, 4, 4, 4, NA, NA, 4, 4, 4, 3, 4, 4, 3, 3, NA, 3, 3,…
Repeat this set of commands using t2_esteem, t1_jobsat, and t2_jobsat. Make sure that those terms select only the relevant items and not others.
analytic_data_occasions <- analytic_data_occasions %>%
rowwise() %>%
mutate(esteem_t1 = mean(c_across(starts_with("t1_esteem")),
na.rm = TRUE)) %>%
mutate(esteem_t2 = mean(c_across(starts_with("t2_esteem")),
na.rm = TRUE)) %>%
mutate(jobsat_t1 = mean(c_across(starts_with("t1_jobsat")),
na.rm = TRUE)) %>%
mutate(jobsat_t2 = mean(c_across(starts_with("t2_jobsat")),
na.rm = TRUE)) %>%
ungroup() %>%
select(-starts_with("t1_esteem")) %>%
select(-starts_with("t2_esteem")) %>%
select(-starts_with("t1_jobsat")) %>%
select(-starts_with("t2_jobsat"))
## Rows: 300
## Columns: 8
## $ id <fct> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17…
## $ age <dbl> 23, 22, 18, 23, 22, 17, 23, 22, 17, NA, 20, 17, 24, 17, N…
## $ sex <fct> male, female, male, female, male, female, male, female, m…
## $ eye_color <fct> blue, brown, hazel, blue, NA, hazel, blue, brown, hazel, …
## $ esteem_t1 <dbl> 3.200, 3.800, 3.800, 3.000, 3.400, 3.500, 3.000, 3.800, 3…
## $ esteem_t2 <dbl> 3.8, 4.4, 4.4, 3.6, 4.0, 4.2, 3.6, 4.4, 4.2, 4.2, 3.4, 4.…
## $ jobsat_t1 <dbl> 4.000, 5.000, 4.400, 3.500, 4.000, 3.800, 3.600, 4.600, 3…
## $ jobsat_t2 <dbl> 4.20, 4.40, 5.00, 4.20, 4.25, 4.40, 4.20, 5.20, 4.00, 4.5…
4.3.5 Pivot to tidy data
But now comes the complicated point wher eyou need to pivot the data to longer.
 In this command we specify the the columns with data by using esteem_t1:jobsat_t2, this selects these two columns and all of the columns between them. Each of these columns represents a dependent variable at a particular time in the format “variable_time” (e.g., esteem_t1). The code names_to = c(“.value”, “time”) explains this format to R. It indicates first part of the column name contains the name of the variable (expressed in the code as “.value”). It also indicates that the second part of the column name represents time. The line names_sep = "_" tells the R that the underscore character is used to separate the first part of the name from the second part of the name. When this code is excuted it creates a tidy version of data set stored in analytic_survey_tidy.
analytic_occasion_tidy <- analytic_data_occasions %>%
pivot_longer(esteem_t1:jobsat_t2,
names_to = c(".value", "time"),
names_sep = "_")
You can see the new data with the print() command. Notice that each participant has multiple rows associated with them.
 The data analytic_data_occasions is appropriate for calculating descriptive statistics and correlations. The data analytic_occasions_items is appropriate for calculating the reliability of the scales you constructed. These data are ready for analysis.
4.4 Basic descriptive statistics
4.4.1 skim()
One approach is the skim() command from the skimr package. This quickly provides the basic descriptive statistics. In the output for this command there are also several columns that beging with p: p0, p25, p50, p75, and p100 (p25 and p75 omitted in output due to space). These columns correspond to the 0th, 25th, 50th, 75th, and 100th percentiles, respectively. The median is the 50th percentile. The interquartile range is the range between p25 and p75. Notice that we run this command on the “wide” version of the data (analytic_data_occasions) rather than tidy version of the data (analytic_occasion_tidy).
## skim_variable n_missing mean sd p0 p50 p100
## 1 age 3 20.52 2.05 17.0 20.0 24.00
## 2 esteem_t1 0 3.40 0.32 2.5 3.4 4.25
## 3 esteem_t2 0 3.93 0.34 3.2 4.0 4.80
## 4 jobsat_t1 0 3.91 0.43 2.0 4.0 5.00
## 5 jobsat_t2 0 4.37 0.42 3.0 4.4 5.25
4.4.2 apa.cor.table()
Another approach is the apa.cor.table() command from the apaTables package. This quickly provides the basic descriptive statistics as well as correlations among variable. As well, it will even create a Word document with this information, see Figure 4.2. Notice that we run this command on the “wide” version of the data (analytic_data_occasions) rather than tidy version of the data (analytic_occasion_tidy).
library(apaTables)
analytic_data_survey %>%
select(where(is.numeric)) %>%
apa.cor.table(filename = "apa_descriptives.doc")
4.4.3 tidyverse
A final approach uses tidyverse commands. This approach is oddly long - and we won’t describe how it works in detail. But, based on the information in the previous chapter you should be able to work out how this code works. Even though this code is long - it provide the ultimate in flexibility. If a new statistics is development that you want to use, you can simply include the command for it in the desired_descriptives list and it will be included in your table. Notice that we run this command on the “wide” version of the data (analytic_data_occasions) rather than tidy version of the data (analytic_occasion_tidy).
library(tidyverse)
# HMisc package must be installed.
# Library command not needed for HMisc package.
desired_descriptives <- list(
mean = ~mean(.x, na.rm = TRUE),
CI95_LL = ~Hmisc::smean.cl.normal(.x)[2],
CI95_UL = ~Hmisc::smean.cl.normal(.x)[3],
sd = ~sd(.x, na.rm = TRUE),
min = ~min(.x, na.rm = TRUE),
max = ~max(.x, na.rm = TRUE),
n = ~sum(!is.na(.x))
)
row_sum <- analytic_data_occasions %>%
summarise(across(.cols = where(is.numeric),
.fns = desired_descriptives,
.names = "{col}___{fn}"))
long_summary <- row_sum %>%
pivot_longer(cols = everything(),
names_to = c("var", "stat"),
names_sep = c("___"),
values_to = "value")
summary_table <- long_summary %>%
pivot_wider(names_from = stat,
values_from = value)
summary_table_rounded <- summary_table %>%
mutate(across(.cols = where(is.numeric),
.fns= round,
digits = 3)) %>%
as.data.frame()
print(summary_table_rounded)
## var mean CI95_LL CI95_UL sd min max n
## 1 age 20.522 20.288 20.756 2.048 17.0 24.00 297
## 2 esteem_t1 3.403 3.366 3.440 0.324 2.5 4.25 300
## 3 esteem_t2 3.927 3.889 3.966 0.337 3.2 4.80 300
## 4 jobsat_t1 3.905 3.856 3.955 0.435 2.0 5.00 300
## 5 jobsat_t2 4.368 4.320 4.416 0.425 3.0 5.25 300
4.4.4 Cronbach’s alpha
If you want Cronbach’s alpha to estimate the reliability of the scale, you can use the alpha command from the psych package with the code below. Note we have to use the item level data we created a copy of, called analytic_data_items. The glimpse() command illustrates this file has all the original items (after reverse-coding has been fixed).
## Rows: 300
## Columns: 14
## $ id <fct> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17…
## $ age <dbl> 23, 22, 18, 23, 22, 17, 23, 22, 17, NA, 20, 17, 24, 17, N…
## $ sex <fct> male, female, male, female, male, female, male, female, m…
## $ eye_color <fct> blue, brown, hazel, blue, NA, hazel, blue, brown, hazel, …
## $ esteem1 <dbl> 3, 4, 4, 3, 3, 3, 3, 4, 4, 4, 3, 4, NA, NA, 3, 3, 3, 3, 3…
## $ esteem2 <dbl> 2, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2, 2, NA, 3, 2, 2, 2, 2, 3,…
## $ esteem3 <dbl> 4, 4, 4, 3, 4, 4, NA, 4, 4, 3, 4, 4, 4, NA, 4, NA, NA, 3,…
## $ esteem4 <dbl> 3, 4, 4, 3, 4, 4, 4, 4, 3, 4, NA, 4, 3, 3, 4, NA, 3, 3, 4…
## $ esteem5 <dbl> 4, 4, 4, 4, 4, NA, NA, 4, 4, 4, 3, 4, 4, 3, 3, NA, 3, 3, …
## $ jobsat1 <dbl> 3, 5, 4, 3, 3, 3, 3, 5, 3, 3, 3, 4, 4, 3, 3, 4, 3, 3, 3, …
## $ jobsat2 <dbl> 5, 5, 5, NA, 5, 5, 4, 5, 4, 4, 3, 5, 3, 4, 5, 5, 4, 3, 5,…
## $ jobsat3 <dbl> 3, NA, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 3,…
## $ jobsat4 <dbl> NA, 5, 5, 4, 4, 4, 4, 5, NA, 4, NA, 5, 4, 4, 4, 5, 4, 3, …
## $ jobsat5 <dbl> 5, NA, 5, 4, 5, 4, 4, 5, 5, 5, 4, NA, 4, 5, 4, 4, 4, 4, 5…
We calculated reliability using psych::alpha() command. Cronbach’s alpha is labeled “raw alpha” in the output. Cronbach’s alpha is an estimate of the proportion of varibilty in observed scores that is due to actual differences among participants (rather than measurement error).
rxx_alpha <- analytic_occasions_items %>%
select(starts_with("t1_esteem")) %>%
psych::alpha()
print(rxx_alpha$total)
## raw_alpha std.alpha G6(smc) average_r S/N ase mean sd median_r
## 0.6622 0.6634 0.6173 0.2827 1.97 0.03035 3.403 0.3239 0.2927


01 Biscuit Town
02 The Locomotive
03 Dum Surfer
05 Bermondsey Bosom (Left)
06 Logos
07 Sublunary
08 Lonely Blue
09 Cadet Limbo
10 Emergency Blimp
11 Czech One
12 A Slide In
13 Vidual
14 Bermondsey Bosom (Right)


BLOODSTONE
5050
Passive: Bloodpact - Starts with 8 charges. Gains 1 charge each time an enemy hero dies within 1675 range. Each charge bestows 1 mana regeneration per second, reduces gold lost from death by 25, and reduces respawn time by 4 seconds. When the bearer dies, restores 400 HP + 30 HP per charge to allied units within 1675 units, then loses a third of its charges. While dead, the bearer continues to receive experience at the death location and gives 1800 unit vision there.
+ 500 Health
+ 400 Mana
+ 9 HP Regeneration
+ 200% Mana Regeneration
The Bloodstone's bright ruby color is unmistakable on the battlefield, as the owner seems to have infinite vitality and spirit.


Need To Learn How Craps Works?
Close Help Window
Roll from your phone!
Leave Game
Thanks for playing!
Leave Game


Networks
Info
There are currently no networks. You can create a network using the form above
{% extends 'dash_base.html' %} {# list of user's instances #} {# standard nav, sidebar, list of instances in main #} {% block sidebar %} {% with current_sidebar="networks" %} {{block.super}} {% endwith %} {% endblock %} {% block headercss %} {% endblock %} {% block main %}
— Networks are virtual quantum networks that provide L2 connectivity to your instances
There are currently no networks. You can create a network using the form above


04_training.py
We will create a 04_training.py
, which contains the logic for the trainer of the network.
The trainer provides random samples of wind speed and target distance, the trebuchet should aim at. After running the information through the forward pass the trainer will evaluate the result of the trebuchet and provide a gradient of the difference between actual and achieved target as feedback.
We first import a necessary libraries.
import socket
import numpy as np
import uuid
import torch
from torch import nn
from swergio import Client, Trigger, MESSAGE_TYPE, MODEL_STATUS
from swergio_toolbox.objects import MutableNumber
We set the component name to trainer, which is use in the communication.
We need to specify the IP and the port of the server as well as the message format and the header length. All of these information have to stay the same across the server and all clients.
COMPONENT_NAME = 'trainer'
PORT = 8080
SERVER = socket.gethostbyname(socket.gethostname())
FORMAT = 'utf-8'
HEADER_LENGTH = 10
For the trainer we first define a constant variable TRAIN_STEPS with the number of total training steps we want to run through once the script is executed.
We then initiate a mutable number as step counter to track how many steps we’ve already been through. This variable needs to be mutable since we will update the value in side the handler function context.
Including the step counter we can initialize the swergio client.
Finally we define a loss function, which we will use to calculate the gradient between actual and achieved target as well as the memory dictionary, which we will use to store the send targets until we get the results.
TRAIN_STEPS = 1000
step_counter = MutableNumber(0)
client = Client(COMPONENT_NAME,SERVER,PORT,FORMAT,HEADER_LENGTH,step_counter = step_counter)
l_fn = nn.MSELoss()
memory = {}
We define a function to generate a new message containing a random sampled wind speeds and target for the trebuchet.
The random target is can be between 20 and 100. While the wind speed is sampled from a normal distribution with factor 5 and can therefore be negative or positive.
After constructing the message as dictionary and adding the samples to the DATA entry, the function also stores the targe value in the component memory dict.
This value is retrieved and used once we get the results from the trebuchet.
To identify the origin of the message throughout the whole process, we set a ROOT_ID which will be passed from message to message.
def new_msg():
nr_of_samples = 100
target = np.random.uniform(20,100,nr_of_samples)
wind = np.random.randn(nr_of_samples)*5 #np.random.uniform(0,5,nr_of_samples)
data_id = uuid.uuid4().hex
d = {'ROOT_ID':data_id,
'ID':uuid.uuid4().hex,
'TYPE': MESSAGE_TYPE.DATA.FORWARD.id,
'DATA': np.stack([wind,target],axis = 1).tolist(),
'TO_ROOM': 'input',
'MODEL_STATUS': MODEL_STATUS.TRAIN.id
}
memory[data_id] = target
return d
Once the samples are processed by the trebuchet, the trainer needs to give feedback how accurate the results are. We therefore use a handler that is triggered by incoming messages in the output room from type DATA.FORWARD.
We extract the achieved target from the DATA entry in the message and retrieve the actual target from our internal memory based on the ROOT_ID of the message (same we provide in new_msg). After cleaning up the memory, we use both values to calculate a loss between the actual and achieved target.
With the pytorch autograd functions we can also calculate the gradient for this loss in respect to the achieved target. This gradient information we will pass down to the trebuchet as our feedback by adding it to the message we send back to the output room as DATA.GRADIENT type.
def backward(msg):
pred = torch.FloatTensor(msg["DATA"])
if msg["ROOT_ID"] not in memory.keys():
return
y = memory[msg["ROOT_ID"]]
y = torch.tensor(y).float()
memory.pop(msg["ROOT_ID"])
l = l_fn(pred,y)
l_gradient = torch.autograd.functional.jacobian(lambda x: l_fn(x,y),pred)
l_gradient = l_gradient.tolist()
return {"ID":msg["ID"],"DATA":l_gradient}
client.add_eventHandler(backward,MESSAGE_TYPE.DATA.GRADIENT,responseRooms='output',trigger=Trigger(MESSAGE_TYPE.DATA.FORWARD,'output'))
To automatically send a new batch of sample data to the network once the feedback of the prior batch is handled, we create a separate handler. The handler function itself just updates the step counter and checks if we did not exceed the total training steps. If that’s the case it will send a new generated message including a new batch.
The handler is triggered once it receives a DATA.GRADIENT message in the input room, which will be the final gradient send by the control model. The response message is sent to the input room, but as a new DATA.FORWARD message.
def new_data(msg, step_counter):
step_counter += 1
if step_counter.value < TRAIN_STEPS:
d = new_msg()
return d
client.add_eventHandler(new_data,MESSAGE_TYPE.DATA.FORWARD,responseRooms='input',trigger=Trigger(MESSAGE_TYPE.DATA.GRADIENT,'input'))
At last the script will send the first message with a sampled batch to the input room. Once we sent the message the client will start listening for responses from the other components.
client.send(new_msg())
client.listen()


( a) The new model for the atomic twin interface was tilted into a viewing direction congruent with . ( b) A superposition structure was constructed by introducing mirror symmetry. ( c), ( d) Simulated electron diffraction data for the zone axis using an SPS with ( c) and without ( d) the twin, see text.


Slycat™ Navbar¶
At the top of every Slycat™ page is the Navbar. Working from left to right, we see the Slycat™ logo, a breadcrumb navigation path, and a set of colored buttons providing dropdown lists categorized by function. Depending on the type of page currently being viewed, the buttons and the contents of the dropdowns will vary. As shown in Figure 3, the Navbar for the main Projects page, the only button available is the green Create button for creating new projects. Since the main Projects page lies outside and above any projects, the breadcrumb navigation path points to the current page, which is simply labeled as Slycat. Figure 4 shows that for Navbars within a project or model page, there can be up to five buttons, including: Create, Edit, Info, Bookmarks, and Delete.
As you move between pages at various levels, the breadcrumb path in the Navbar will change to reflect your current location. The path has the format Project Name / Model Name. The path can be used to navigate within the hierarchy. Clicking on the Project Name will take you to that project’s page with its list of associated models. Hovering over the Project Name will display the project description, the project members, the date of creation, and who created it (Figure 5). Similarly, hovering over the Model Name will display the model description, the date of creation, and who created it.