How to fit Stargazer tables to the page width (! please not scale the table) - width

Is there a way to get page-width tables by slightly revising the tex code generated from Stargazer?
Tex code generated from Stargazer does not adjust the table's width, so it is often too long or narrow.
A short example of the original Stargazer code is as follows. You could offer advice applied to the code. That is, how to slightly revise the code so that the table width fits the page width in a way not scaling the table.
\begin{table}[!htbp] \centering
\caption{}
\label{}
\begin{tabular}{#{\extracolsep{5pt}}lD{.}{.}{-3} }
\\[-1.8ex]\hline
\hline \\[-1.8ex]
\\[-1.8ex] & \multicolumn{1}{c}{Duration Gap in 0.5M} \\
\hline \\[-1.8ex]
Constant & 8.496^{***} \\
& (0.060) \\
& \\
\hline \\[-1.8ex]
Observations & \multicolumn{1}{c}{2,241} \\
R$^{2}$ & \multicolumn{1}{c}{0.820} \\
Adjusted R$^{2}$ & \multicolumn{1}{c}{0.820} \\
\hline
\hline \\[-1.8ex]
\end{tabular}
\end{table}
I found the solutions, such as using \resizebox, but the scales of the table are changed.
Other solutions using different packages (i.e. tabularX), seem to need many changes in the code generated from Stargazer. Is there a way to get page-width tables using the Stargazer code without making many changes?

Start from here
library(stargazer)
linear.1 <- lm(mpg ~ cyl + disp + hp, data=mtcars)
linear.2 <- lm(mpg ~ log(cyl) + disp + hp, data=mtcars)
stargazer(linear.1, linear.2, type="latex")
% Table created by stargazer v.5.2.3 by Marek Hlavac, Social Policy Institute. E-mail: marek.hlavac at gmail.com
% Date and time: Mi, Jan 11, 2023 - 17:06:46
\begin{table}[!htbp] \centering
\caption{}
\label{}
\begin{tabular}{#{\extracolsep{5pt}}lcc}
\\[-1.8ex]\hline
\hline \\[-1.8ex]
& \multicolumn{2}{c}{\textit{Dependent variable:}} \\
\cline{2-3}
\\[-1.8ex] & \multicolumn{2}{c}{mpg} \\
\\[-1.8ex] & (1) & (2)\\
\hline \\[-1.8ex]
cyl & $-$1.227 & \\
& (0.797) & \\
& & \\
log(cyl) & & $-$7.833$^{*}$ \\
& & (4.136) \\
& & \\
disp & $-$0.019$^{*}$ & $-$0.018$^{*}$ \\
& (0.010) & (0.010) \\
& & \\
hp & $-$0.015 & $-$0.014 \\
& (0.015) & (0.014) \\
& & \\
Constant & 34.185$^{***}$ & 40.165$^{***}$ \\
& (2.591) & (5.139) \\
& & \\
\hline \\[-1.8ex]
Observations & 32 & 32 \\
R$^{2}$ & 0.768 & 0.777 \\
Adjusted R$^{2}$ & 0.743 & 0.753 \\
Residual Std. Error (df = 28) & 3.055 & 2.996 \\
F Statistic (df = 3; 28) & 30.877$^{***}$ & 32.488$^{***}$ \\
\hline
\hline \\[-1.8ex]
\textit{Note:} & \multicolumn{2}{r}{$^{*}$p$<$0.1; $^{**}$p$<$0.05; $^{***}$p$<$0.01} \\
\end{tabular}
\end{table}
and change
\begin{tabular}{#{\extracolsep{5pt}}
to
\begin{tabular*}{\textwidth}{c #{\extracolsep{\fill}}
Note that you have an option inside stargazer to adjust column width, I get a very similar result within stargazer via:
stargazer(linear.1, linear.2, type="latex", column.sep.width = "120pt")

Related

Loop in a list of tuples joining elements of each tuple

I have been trying to make this code better/faster and more sustainable but didn't succeed to do improve it yet.
Basically I need to loop in a list of tuples, and concatenate each element of the tuple with the dataframe filter expression exactly as showed in the solution. However the tuples in my list don't have the same length and they can change and have different length time to time, sometimes I can get tuples with less than 4 elements in each, other times more than 6 or even 7/8 and so on.
My solution works but I will need to edit every time the length of my tuples increases, and I know isn't the most efficient solution. How would I iterate inside the tuples using the length of each tuple in my favor in order to avoid nested ifs?
Appreciate your advises and comments
Actual list:
Comb = [(),
('RD00',),
('RDC2',),
('RDC3',),
('RDC4',),
('RD00', 'RDC2'),
('RD00', 'RDC3'),
('RD00', 'RDC4'),
('RDC2', 'RDC3'),
('RDC2', 'RDC4'),
('RDC3', 'RDC4'),
('RD00', 'RDC2', 'RDC3'),
('RD00', 'RDC2', 'RDC4'),
('RD00', 'RDC3', 'RDC4'),
('RDC2', 'RDC3', 'RDC4'),
('RD00', 'RDC2', 'RDC3', 'RDC4')]
I came up with this Solution, i need to concatenate the tuples elements in each tuple and add the expression in front of each element in the tuple:
for p in comb:
if len(p) == 1:
print(''"(fF2_Principal['Messagetype']=="'{}'.format("'"+p[0]+"')"))
if len(p) == 2:
print(''"(fF2_Principal['Messagetype']=="'{} & '" (fF2_Principal['Messagetype']=="'{}'.format("'"+p[0]+"')", "'"+p[1]+"')"))
elif len(p) == 3:
print(''"(fF2_Principal['Messagetype']=="'{} & '"(fF2_Principal['Messagetype']=="'{} & '"(fF2_Principal['Messagetype']=="'{}'.format("'"+p[0]+"')", "'"+p[1]+"')","'"+p[2]+"')"))
elif len(p) == 4:
print(''"(fF2_Principal['Messagetype']=="'{} & '"(fF2_Principal['Messagetype']=="'{} & '" (fF2_Principal['Messagetype']=="'{} & '"(fF2_Principal['Messagetype']=="'{}'.format("'"+p[0]+"')", "'"+p[1]+"')","'"+p[2]+"')","'"+p[3]+"')"))
elif len(p) == 5: # not done yet, my previous data had 5 elements in one tuple
print('{} : {} : {} : {} : {}'.format(p[0], p[1],p[2],p[3],p[4]))
The code above generates the following results, which works for my purpose, however I cant be monitoring the data to see when a different length of tuples will be present.
Results:
(fF2_Principal['Messagetype']=='RD00')
(fF2_Principal['Messagetype']=='RDC2')
(fF2_Principal['Messagetype']=='RDC3')
(fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC2')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC3')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RDC2') & (fF2_Principal['Messagetype']=='RDC3')
(fF2_Principal['Messagetype']=='RDC2') & (fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RDC3') & (fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC2') &
(fF2_Principal['Messagetype']=='RDC3')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC2') &
(fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC3') &
(fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RDC2') & (fF2_Principal['Messagetype']=='RDC3') &
(fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC2') &
(fF2_Principal['Messagetype']=='RDC3') & (fF2_Principal['Messagetype']=='RDC4')
Really appreciate your comments and advises in how to improve this code and make it more sustainable.
The easiest way to do this is using a list comprehension (to write each entry in the tuple's text individually) along with str.join() to patch an arbitrary number of them together.
>>> for tup in Comb:
... msg = " & ".join(
... f"(fF2_Principal['Messagetype']=='{e}')" for e in tup
... )
... print(msg)
...
(fF2_Principal['Messagetype']=='RD00')
(fF2_Principal['Messagetype']=='RDC2')
(fF2_Principal['Messagetype']=='RDC3')
(fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC2')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC3')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RDC2') & (fF2_Principal['Messagetype']=='RDC3')
(fF2_Principal['Messagetype']=='RDC2') & (fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RDC3') & (fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC2') & (fF2_Principal['Messagetype']=='RDC3')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC2') & (fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC3') & (fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RDC2') & (fF2_Principal['Messagetype']=='RDC3') & (fF2_Principal['Messagetype']=='RDC4')
(fF2_Principal['Messagetype']=='RD00') & (fF2_Principal['Messagetype']=='RDC2') & (fF2_Principal['Messagetype']=='RDC3') & (fF2_Principal['Messagetype']=='RDC4')
You'll note that this produces an empty line for the first element. If you don't want to print anything, even an empty line, then you can add if len(e) > 0 to the end of the comprehension, right after for e in tup, which will filter tuples out if they contain 0 elements.

In python, headings not in the same row

I extracted three columns from a larger data frame (recent_grads) as follows...
df = recent_grads.groupby('Major_category')['Men', 'Women'].sum()
However, when I print df, it comes up as follows...
Men Women
Major_category
Agriculture & Natural Resources 40357.0 35263.0
Arts 134390.0 222740.0
Biology & Life Science 184919.0 268943.0
Business 667852.0 634524.0
Communications & Journalism 131921.0 260680.0
Computers & Mathematics 208725.0 90283.0
Education 103526.0 455603.0
Engineering 408307.0 129276.0
Health 75517.0 387713.0
Humanities & Liberal Arts 272846.0 440622.0
Industrial Arts & Consumer Services 103781.0 126011.0
Interdisciplinary 2817.0 9479.0
Law & Public Policy 91129.0 87978.0
Physical Sciences 95390.0 90089.0
Psychology & Social Work 98115.0 382892.0
Social Science 256834.0 273132.0
How do I get Major_category heading in the same row as Men and Women headings? I tried to put the three columns in a new data frame as follows...
df1 = df[['Major_category', 'Men', 'Women']].copy()
This gives me an error (Major_category not in index)
Hi man you should try reset_index https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.reset_index.html:
df = df.groupby('Major_category')['Men', 'Women'].sum()
# Print the output.
md = df.reset_index()
print(md)
Seems like you want to convert the groupby object back to a dataframe try:
df['Major_category'].apply(pd.DataFrame)

Print text file as two separate lists

I am new to Python and stackoverflow :). I have a txt file which I need to print from. This is the txt file called DOB and has the following info:
Orville Wright 21 July 1988
Rogelio Holloway 13 September 1988
Marjorie Figueroa 9 October 1988
Debra Garner 7 February 1988
I need to print and display the list like this:
1. Orville Wright
2. Regelio Holloway
3. ......
list item
1. 21 July 1988
2. 13 September 1988
3. .......
My code below opens the txt file twice and I don't think that is effective. Help!
dob = open('DOB.txt', 'r')
for i, line in enumerate(dob, 1):
name = line.split()
name_surname = str(i) + "." + " " + name[0] + " " + name[1]
print(name_surname)
dob = open('DOB.txt', 'r')
for i, line in enumerate(dob, 1):
date = line.split()
day_to_year = str(i) + "." + " " + date[2] + " " + date[3] + " " + date[4]
print(day_to_year)
dob.close()
Calling read() reads through the entire file and leaves the read cursor at the end of the file (with nothing more to read).
Once a file has been read, with read() you can use seek(0) to return the read cursor to the start of the file (docs are here). No need to open the file twice.
Use file.seek to jump to a specific position in a file. However, think about whether it is really necessary to go through the file again. Maybe there is a better option.
There can be another way of solving this problem, which is read the data once, have it saved in proper lists/variables and use it as you want. For example print it out in the format way you want.
#!/usr/bin/python
file = "/Users/rprakash/python/records.txt"
data = open(file, 'r')
for i, line in enumerate(data, 1):
details = line.split()
name = details[0] + " " + details[1]
print str(i) + ". " + name
data.seek(0)
for i, line in enumerate(data, 1):
details = line.split()
dob = details[2] + " " + details[3] + " " + details[4]
print str(i) + ". " + dob
Output:
1. Orville Wright
2. Rogelio Holloway
3. Marjorie Figueroa
4. Debra Garner
1. 21 July 1988
2. 13 September 1988
3. 9 October 1988
4. 7 February 1988

Comparing and highlighting time values

I am parsing and analyzing large data sets and attempting to highlight rows that share the same time of occurrence. This is a smaller piece of a larger macro and is currently the only piece not working (the rest works rather well!) I am trying to compare each time to the time before it and after it in order to capture all occurrences. If I compare just the time before, or just the time after, you can probably see how that would miss a lot of values. Code:
'Hightlights trade structures via time
Do
DoEvents
row_number = row_number + 1
'row_color_tester is a proxy for testing trade time "structure principle"
row_color_tester = row_number
tradeTime = ActiveSheet.Range("B" & row_number)
If tradeTime = Range("B" & (row_color_tester + 1)) Or tradeTime = Range("B" & (row_color_tester - 1)) Then
ActiveCell.EntireRow.Interior.ColorIndex = 8
End If
Loop Until row_number = lastRow + 1
Sample data:
16:01:30
15:37:56
15:08:38
15:08:38
14:40:56
14:29:36
14:28:10
14:28:10
14:23:48
14:21:49
14:21:49
14:21:49
14:21:49
14:21:49
14:21:49
14:20:01
14:20:01
14:20:01
14:20:01
14:20:01
14:20:01
14:19:52
14:19:52
14:19:52
14:19:52
14:19:52
14:19:52
14:19:43
14:18:57
14:18:43
14:18:34
14:17:50
14:17:50
14:17:46
14:17:46
14:17:13
14:16:50
14:16:50
14:16:50
14:16:50
14:16:50
14:16:50
14:14:59
14:14:59
14:14:59
14:14:59
14:14:59
14:14:59
14:12:38
14:11:27
14:10:11
14:10:11
14:07:17
13:56:46
13:55:16
13:55:16
13:55:16
13:51:59
13:51:59
13:51:59
13:51:59
13:51:59
13:51:59
13:51:39
13:51:39
13:51:39
13:51:39
13:51:39
13:51:39
13:50:45
13:50:45
13:50:45
13:50:45
13:50:45
13:50:45
13:46:49
13:46:49
13:45:12
13:45:12
13:44:31
13:44:31
13:44:31
13:44:31
13:44:31
13:44:31
13:43:32
13:43:32
13:43:32
13:43:32
13:43:32
13:43:32
13:41:58
13:35:46
13:35:46
13:35:46
13:35:46
13:35:46
13:35:46
13:35:25
13:35:25
13:35:19
13:35:19
13:35:07
13:35:07
13:35:07
13:35:07
13:35:07
13:35:07
13:27:57
13:27:57
13:20:40
13:20:40
As to why it is not working, times are tricky, they essentially are a formatted number. For example (0.598483796296296 to 0.598483796296300) will format to 14:21:49. This is why the way you have will sometimes work and sometimes not.
to fix it add .text to the end of the three ranges:
ActiveSheet.Range("B" & row_number).Text
This way you are only comparing the formatted text.
Also it is good practice not to use activecell. Use:
Rows(row_number).entirerow. Interior.colorindex = 8
I have had to do something like this multiple times in the past. I always use the code found here:
http://www.cpearson.com/excel/findall.aspx
Assuming the times start in row 2 and column 1, a simple solution, can be attained with the following conditional formatting:
for the following range:

How to convert excel data to json at frontend side

I want to convert some excel data to JSON. Plan is to get my excel file from D drive, read data and make some UI for this. Can any one please help me out?
Data is like this :-
country year 1 2 3 4
Netherlands 1970 3603 4330 5080 5820
Netherlands 1971 3436 4165 4929 5693
Netherlands 1972 3384 4122 4899 5683
Sweden 1970 1479 1963 2520 3132
Sweden 1971 1497 1985 2547 3163
Sweden 1972 1419 1894 2445 3055
You could of course always use Excel VBA, as you are already working with Excel. The following sub exports the used range of the current sheet as valid JSON into a .js-file:
Option Explicit
Sub jsonex()
Dim fname, q$, str$, lineend$, na, va, ur As Range, i%, j%, ncols%, nrows%
Set ur = Application.ActiveSheet.UsedRange
' set a few variables ...
na = ur.Rows(1): ncols = ur.Columns.Count: nrows = ur.Rows.Count: lineend = ",": q = """"
fname = "d:\tmp\data.js" ' prefedined filename
' fname = Application.GetSaveAsFilename ' or use file selector box ...
Open fname For Output As #1
Print #1, "var data=["
For i = 2 To ur.Rows.Count
va = ur.Rows(i)
str = ""
For j = 1 To ncols
str = str & "," & q & na(1, j) & q & ":" & q & va(1, j) & q
Next
If (i = nrows) Then lineend = "];"
Print #1, " {" & Mid(str, 2) & "}" & lineend
Next
Close #1
End Sub
This produces the file d:\tmp\data.js with
var data=[
{"Country":"Netherlands","year":"1970","1":"3603","2":"4330","3":"5080","4":"5820"},
{"Country":"Netherlands","year":"1971","1":"3436","2":"4165","3":"4929","4":"5693"},
{"Country":"Netherlands","year":"1972","1":"3384","2":"4122","3":"4899","4":"5683"},
{"Country":"Sweden","year":"1970","1":"1479","2":"1963","3":"2520","4":"3132"},
{"Country":"Sweden","year":"1971","1":"1497","2":"1985","3":"2547","4":"3163"},
{"Country":"Sweden","year":"1972","1":"1419","2":"1894","3":"2445","4":"3055"}];
Once you got it in this JSON format it is up to you to convert it into a different Array/Object structure by using plain JavaScript like
var da={};
data.slice(1).forEach(function(e){
var arr=[e[1],e[2],e[3],e[4]];
if (!da[e.country]) da[e.country]={}
da[e.country][e.year]=arr;
});
Maybe this is more the format you would like ("beautified" JSON.stringify(da)):
{"Netherlands":{"1970":["3603","4330","5080","5820"],
"1971":["3436","4165","4929","5693"],
"1972":["3384","4122","4899","5683"]},
"Sweden": {"1970":["1479","1963","2520","3132"],
"1971":["1497","1985","2547","3163"],
"1972":["1419","1894","2445","3055"]}}
Your JSON data could look like this:
[
{"country":"Netherlands', "year":1970, "1":3603, "2":4330, "3": 5080, "4":5820},
{"country":"Netherlands", "year":1971, ...}
...
]

Resources