Suppose you have several variables:
+--------------------------+------------+------------+-----------+-------+
| | Population | Median_Age | Sex_Ratio | GDP |
| Country | | | | |
+--------------------------+------------+------------+-----------+-------+
| United States of America | 3999 | | 1.01 | 16000 |
+--------------------------+------------+------------+-----------+-------+
| Afghanistan | 544 | 19 | 0.97 | 4456 |
+--------------------------+------------+------------+-----------+-------+
| China | 5000 | 26 | 0.96 | 10000 |
+--------------------------+------------+------------+-----------+-------+
Let us suppose that Median_Age under United States of America is empty.
How do I replace this missing value to 27 if Country contains United, or United States?
Here's a modified example that better illustrates the solution:
clear
input strL Country Population Median_Age Sex_Ratio GDP
"United States of America" 3999 . 1.01 5000
"Afghanistan" 544 19 0.97 457
"United Emirates" 7546 44 7.01 2000
"China" 10000 26 0.96 3400
"United Fictionary Nation" 6789 . 8.03 7689
end
list, abbreviate(10)
+-----------------------------------------------------------------------+
| Country Population Median_Age Sex_Ratio GDP |
|-----------------------------------------------------------------------|
1. | United States of America 3999 . 1.01 5000 |
2. | Afghanistan 544 19 .97 457 |
3. | United Emirates 7546 44 7.01 2000 |
4. | China 10000 26 .96 3400 |
5. | United Fictionary Nation 6789 . 8.03 7689 |
+-----------------------------------------------------------------------+
replace Median_Age = 27 if ( strmatch(Country, "*United States*") | ///
strmatch(Country, "*United*") ) & ///
missing(Median_Age)
list, abbreviate(10)
+-----------------------------------------------------------------------+
| Country Population Median_Age Sex_Ratio GDP |
|-----------------------------------------------------------------------|
1. | United States of America 3999 27 1.01 5000 |
2. | Afghanistan 544 19 .97 457 |
3. | United Emirates 7546 44 7.01 2000 |
4. | China 10000 26 .96 3400 |
5. | United Fictionary Nation 6789 27 8.03 7689 |
+-----------------------------------------------------------------------+
Related
As I am still quite new to web scraping I am currently practicing some basics such as this one. I have scraped the categories from 'th' tag and the players from the 'tr' tag and appended it to a couple empty lists. The categories come out fine from get_text(), but when I try printing the players it has a number rank before the first letter of the name, and the player's team abbreviation letters after the last name.
3 things I am trying to do:
1)output only the first and last name of each player by doing some slicing from the list but I cannot figure out any easier way to do it. There is probably a quicker way inside the tags where I can call the class or using soup.findAll again in the html, or something else I am unware of, but I currently do not know how or what I am missing.
2)take the number ranks before the name and append it to an empty list.
3)take the 3 last abbreviated letters and append it to an empty list
Any suggestions would be much appreciated!
from bs4 import BeautifulSoup as bs4
import requests
import pandas as pd
from time import sleep
players = []
categories = []
url ='https://www.espn.com/nba/stats/player/_/table/offensive/sort/avgPoints/dir/desc'
source = requests.get(url)
soup = bs4(source.text, 'lxml')
for i in soup.findAll('th'):
c = i.get_text()
categories.append(c)
for i in soup.findAll('tr'):
player = i.get_text()
players.append(player)
players = players[1:51]
print(categories)
print(players)
Apis are always the best way to go in my opinion.
However, this can also be done with pandas .read_html() (it uses beautifulsoup under the hood to parse the table).
import pandas as pd
url = 'https://www.espn.com/nba/stats/player/_/table/offensive/sort/avgPoints/dir/desc'
dfs = pd.read_html(url)
dfs[0][['Name','Team']] = dfs[0]['Name'].str.extract('^(.*?)([A-Z]+)$', expand=True)
df = dfs[0].join(dfs[1])
Output:
print (df[['RK','Name','Team','POS']])
RK Name Team POS
0 1 James Harden HOU SG
1 2 Stephen Curry GS PG
2 3 Bradley Beal WSH SG
3 4 Trae Young ATL PG
4 5 Kevin Durant BKN SF
5 6 CJ McCollum POR SG
6 7 Kyrie Irving BKN PG
7 8 Jaylen Brown BOS SG
8 9 Giannis Antetokounmpo MIL PF
9 10 Jayson Tatum BOS PF
10 11 Damian Lillard POR PG
11 12 Luka Doncic DAL PG
12 13 Collin Sexton CLE PG
13 14 Paul George LAC SG
14 15 Brandon Ingram NO SF
15 16 Nikola Jokic DEN C
16 17 LeBron James LAL SF
17 18 Zach LaVine CHI SG
18 19 Christian Wood HOU PF
19 20 Kawhi Leonard LAC SF
20 21 Joel Embiid PHI C
21 22 Jerami Grant DET PF
22 23 Anthony Davis LAL PF
23 24 Jamal Murray DEN PG
24 25 Julius Randle NY PF
25 26 Malcolm Brogdon IND PG
26 27 Fred VanVleet TOR SG
27 28 Nikola Vucevic ORL C
28 28 Donovan Mitchell UTAH SG
29 30 Terry Rozier CHA PG
30 31 Devin Booker PHX SG
31 32 Khris Middleton MIL SF
32 33 Terrence Ross ORL SG
33 33 Victor Oladipo IND SG
34 35 Russell Westbrook WSH PG
35 36 Domantas Sabonis IND PF
36 36 De'Aaron Fox SAC PG
37 38 Zion Williamson NO SF
38 39 Tobias Harris PHI SF
39 40 Bam Adebayo MIA C
40 41 DeMar DeRozan SA SG
41 41 D'Angelo Russell MIN SG
42 43 Gordon Hayward CHA SF
43 44 Kyle Lowry TOR PG
44 44 Shai Gilgeous-Alexander OKC SG
45 46 Mike Conley UTAH PG
46 47 Malik Beasley MIN SG
47 48 RJ Barrett NY SG
48 49 Thomas Bryant WSH C
49 50 Pascal Siakam TOR PF
Is this what you want?
import requests
from bs4 import BeautifulSoup
from tabulate import tabulate
url = "https://www.espn.com/nba/stats/player/_/table/offensive/sort/avgPoints/dir/desc"
soup = BeautifulSoup(requests.get(url).text, "html.parser")
table_data = [
[r // 2, i.find("a").getText(), i.find("span").getText()] for r, i in
enumerate(soup.find_all("td", class_="Table__TD"), start=1)
if i.find("a") and i.find("span")
]
print(tabulate(table_data, headers=["Rank", "Name", "Team"], tablefmt="pretty"))
Output:
| Rank | Name | Team |
+------+-------------------------+------+
| 1 | James Harden | HOU |
| 2 | Stephen Curry | GS |
| 3 | Bradley Beal | WSH |
| 4 | Trae Young | ATL |
| 5 | Kevin Durant | BKN |
| 6 | CJ McCollum | POR |
| 7 | Kyrie Irving | BKN |
| 8 | Jaylen Brown | BOS |
| 9 | Giannis Antetokounmpo | MIL |
| 10 | Jayson Tatum | BOS |
| 11 | Damian Lillard | POR |
| 12 | Luka Doncic | DAL |
| 13 | Collin Sexton | CLE |
| 14 | Paul George | LAC |
| 15 | Brandon Ingram | NO |
| 16 | Nikola Jokic | DEN |
| 17 | LeBron James | LAL |
| 18 | Zach LaVine | CHI |
| 19 | Christian Wood | HOU |
| 20 | Kawhi Leonard | LAC |
| 21 | Joel Embiid | PHI |
| 22 | Jerami Grant | DET |
| 23 | Anthony Davis | LAL |
| 24 | Jamal Murray | DEN |
| 25 | Julius Randle | NY |
| 26 | Malcolm Brogdon | IND |
| 27 | Fred VanVleet | TOR |
| 28 | Nikola Vucevic | ORL |
| 29 | Donovan Mitchell | UTAH |
| 30 | Terry Rozier | CHA |
| 31 | Devin Booker | PHX |
| 32 | Khris Middleton | MIL |
| 33 | Terrence Ross | ORL |
| 34 | Victor Oladipo | IND |
| 35 | Russell Westbrook | WSH |
| 36 | Domantas Sabonis | IND |
| 37 | De'Aaron Fox | SAC |
| 38 | Zion Williamson | NO |
| 39 | Tobias Harris | PHI |
| 40 | Bam Adebayo | MIA |
| 41 | DeMar DeRozan | SA |
| 42 | D'Angelo Russell | MIN |
| 43 | Gordon Hayward | CHA |
| 44 | Kyle Lowry | TOR |
| 45 | Shai Gilgeous-Alexander | OKC |
| 46 | Mike Conley | UTAH |
| 47 | Malik Beasley | MIN |
| 48 | RJ Barrett | NY |
| 49 | Thomas Bryant | WSH |
| 50 | Pascal Siakam | TOR |
+------+-------------------------+------+
Always ask you - Is there an easier way?
Yes it is and you should go it :)
If you wanna scrape, first take a look if you really have to scrape content from the website or if there is an api that provide the information well structured.
Example requesting api
import requests
import pandas as pd
url = "https://site.web.api.espn.com/apis/common/v3/sports/basketball/nba/statistics/byathlete?region=us&lang=en&contentorigin=espn&isqualified=true&page=1&limit=50&sort=offensive.avgPoints%3Adesc&season=2021&seasontype=2"
headers = {"user-agent": "Mozilla/5.0"}
response = requests.get(url, headers=headers)
response.raise_for_status()
ranking=[]
for i,player in enumerate(response.json()['athletes'], start=1):
rank = i
name = player['athlete']['displayName']
team = player['athlete']['teamShortName']
category = player['athlete']['position']['abbreviation']
ranking.append({'rank':rank, 'name':name, 'team':team, 'category':category})
df = pd.DataFrame(ranking)
df
Output data frame
rank name team category
1 James Harden HOU SG
2 Stephen Curry GS PG
3 Bradley Beal WSH SG
4 Trae Young ATL PG
5 Kevin Durant BKN SF
6 CJ McCollum POR SG
7 Kyrie Irving BKN PG
8 Jaylen Brown BOS SG
9 Giannis Antetokounmpo MIL PF
10 Jayson Tatum BOS PF
But to answer your question
You can also do it with BeautifulSoup, but it is much more error-prone in my opinion:
from bs4 import BeautifulSoup
import requests
import pandas as pd
data = []
url ='https://www.espn.com/nba/stats/player/_/table/offensive/sort/avgPoints/dir/desc'
source = requests.get(url)
soup = BeautifulSoup(source.text, 'lxml')
for i in soup.select('tr')[1:]:
if i.select_one('td'):
rank = i.select_one('td').get_text()
if i.select_one('div > a'):
player = i.select_one('div > a').get_text()
if i.select_one('div > span'):
team =i.select_one('div > span').get_text()
data.append({'rank':rank, 'player':player, 'team':team})
pd.DataFrame(data)
If you do not wanna use css selectors, you can also do
for i in soup.find_all('tr')[1:]:
if i.find('td'):
rank = i.find('td').get_text()
if i.find('a'):
player = i.find('a').get_text()
if i.find('span'):
team =i.find('span').get_text()
I have the following text:
KN_Divers_Blau | -6.429897 8.010333 -0.80 0.422 -22.14101 9.28122
Ind_ROA_Ave | .3407456 .3389998 1.01 0.315 -.3241539 1.005645
Ind_Tobin_Q1_Ave | -.5065654 .2104229 -2.41 0.016 -.9192797 -.0938511
Ind_Growth_Ave | -1.404911 1.852805 -0.76 0.448 -5.038922 2.229101
Pat_Dum | -18.31015 5.452194 -3.36 0.001 -29.00385 -7.616457
|
year |
1981 | -5.575117 2.805975 -1.99 0.047 -11.07863 -.0715993
1982 | -6.171125 5.447273 -1.13 0.257 -16.85517 4.512919
1983 | -11.8282 8.84588 -1.34 0.181 -29.17812 5.521726
1984 | -20.39602 11.73682 -1.74 0.082 -43.41611 2.624069
1985 | -23.7097 14.29652 -1.66 0.097 -51.75028 4.330874
1986 | -29.43432 16.51849 -1.78 0.075 -61.83297 2.964339
1987 | -35.30922 18.5138 -1.91 0.057 -71.62137 1.002936
1988 | -49.09056 19.95166 -2.46 0.014 -88.22289 -9.958242
1989 | -53.98487 21.88913 -2.47 0.014 -96.91725 -11.05248
1990 | -67.58938 23.41111 -2.89 0.004 -113.5069 -21.67185
1991 | -78.59984 25.52294 -3.08 0.002 -128.6594 -28.54026
1992 | -88.89806 28.22778 -3.15 0.002 -144.2628 -33.53332
1993 | -98.40131 31.35391 -3.14 0.002 -159.8975 -36.90512
1994 | -102.953 33.25041 -3.10 0.002 -168.1689 -37.73712
1995 | -116.2812 37.25681 -3.12 0.002 -189.355 -43.20726
1996 | -118.0298 38.76035 -3.05 0.002 -194.0527 -42.00698
1997 | -118.4325 38.4338 -3.08 0.002 -193.8149 -43.05017
1998 | -123.8912 37.96394 -3.26 0.001 -198.352 -49.43038
1999 | -128.3908 39.44807 -3.25 0.001 -205.7626 -51.01913
2000 | -133.2699 40.31404 -3.31 0.001 -212.3401 -54.19972
2001 | -126.159 37.63045 -3.35 0.001 -199.9658 -52.35232
2002 | -119.8247 36.05833 -3.32 0.001 -190.5479 -49.10146
2003 | -109.2157 34.54755 -3.16 0.002 -176.9758 -41.45563
2004 | -114.1801 33.58204 -3.40 0.001 -180.0465 -48.31378
2005 | 0 (omitted)
|
_cons | -187.8645 62.81122 -2.99 0.003 -311.0597 -64.66936
KN_Divers_Blau | -6.57637 8.068413 -0.82 0.415 -22.4014 9.248663
Ind_ROA_Ave | .3641781 .3411348 1.07 0.286 -.3049088 1.033265
Ind_Tobin_Q1_Ave | -.5070564 .2105863 -2.41 0.016 -.9200911 -.0940217
Ind_Growth_Ave | -1.424116 1.871656 -0.76 0.447 -5.095101 2.246869
Pat_Dum | -18.51642 5.463958 -3.39 0.001 -29.23319 -7.799652
|
year |
1981 | -4.660021 2.721933 -1.71 0.087 -9.998702 .678659
1982 | -5.557028 5.497126 -1.01 0.312 -16.33885 5.224794
1983 | -10.63977 8.795378 -1.21 0.227 -27.89063 6.611104
1984 | -18.76668 11.39263 -1.65 0.100 -41.1117 3.578331
1985 | -23.61831 14.32697 -1.65 0.099 -51.71861 4.481984
1986 | -29.10203 16.61986 -1.75 0.080 -61.6995 3.495445
1987 | -34.29028 18.46377 -1.86 0.063 -70.50431 1.923745
1988 | -48.44084 19.75174 -2.45 0.014 -87.18104 -9.70065
1989 | -54.73721 22.04372 -2.48 0.013 -97.97281 -11.50162
1990 | -67.16001 23.65404 -2.84 0.005 -113.554 -20.76601
1991 | -77.92565 25.97627 -3.00 0.003 -128.8744 -26.97694
1992 | -88.53438 28.49949 -3.11 0.002 -144.432 -32.63673
1993 | -97.72113 31.57967 -3.09 0.002 -159.6601 -35.78213
1994 | -102.3819 33.38187 -3.07 0.002 -167.8557 -36.90815
1995 | -115.8907 37.23702 -3.11 0.002 -188.9258 -42.85566
1996 | -118.6755 39.02702 -3.04 0.002 -195.2214 -42.12961
1997 | -118.675 38.75563 -3.06 0.002 -194.6886 -42.66145
1998 | -124.622 38.53307 -3.23 0.001 -200.1991 -49.04492
1999 | -128.1722 39.91359 -3.21 0.001 -206.4569 -49.88741
2000 | -133.1516 40.6607 -3.27 0.001 -212.9017 -53.40144
2001 | -126.7362 38.51777 -3.29 0.001 -202.2833 -51.18914
2002 | -119.7739 36.83191 -3.25 0.001 -192.0145 -47.53344
2003 | -108.5075 34.97694 -3.10 0.002 -177.1097 -39.90524
2004 | -111.8748 33.35352 -3.35 0.001 -177.2929 -46.45662
2005 | 0 (omitted)
|
_cons | -178.691 61.08993 -2.93 0.003 -298.5101 -58.87189
And am looking for a regex expression that removes all the years, so the output would like something this:
KN_Divers_Blau | -6.429897 8.010333 -0.80 0.422 -22.14101 9.28122
Ind_ROA_Ave | .3407456 .3389998 1.01 0.315 -.3241539 1.005645
Ind_Tobin_Q1_Ave | -.5065654 .2104229 -2.41 0.016 -.9192797 -.0938511
Ind_Growth_Ave | -1.404911 1.852805 -0.76 0.448 -5.038922 2.229101
Pat_Dum | -18.31015 5.452194 -3.36 0.001 -29.00385 -7.616457
|
|
_cons | -187.8645 62.81122 -2.99 0.003 -311.0597 -64.66936
KN_Divers_Blau | -6.57637 8.068413 -0.82 0.415 -22.4014 9.248663
Ind_ROA_Ave | .3641781 .3411348 1.07 0.286 -.3049088 1.033265
Ind_Tobin_Q1_Ave | -.5070564 .2105863 -2.41 0.016 -.9200911 -.0940217
Ind_Growth_Ave | -1.424116 1.871656 -0.76 0.447 -5.095101 2.246869
Pat_Dum | -18.51642 5.463958 -3.39 0.001 -29.23319 -7.799652
|
|
_cons | -178.691 61.08993 -2.93 0.003 -298.5101 -58.87189
I'm extremely new to regex, and have tried searching for the following and replace it with nothing in Notepad++:
year.*[\n].*1981.*[\n].*2005
The problem is it finds all the values in between the first years columns and the second one and removes everything in between.
Is there a way to have the search term find each years column once? (So in my example, it would find and replace the years column twice in total)
Many thanks in advance.
You may use the following pattern:
^\s*year.*(?:[\r\n]+\s*\d{4}\b.*)*[\r\n]+
..and replace with an empty string.
Demo.
Breakdown:
^ Beginning of line.
\s* Match zero or more whitespace characters.
year.* Match "year" followed by any number of characters.
(?: Start of a non-capturing group.
[\r\n]+ Match one or more line-break character.
\s* Match zero or more whitespace characters.
\d{4}\b.* Match four digits followed by any number of characters.
) Close the non-capturing group.
* Match zero or more occurrences of the previous group.
[\r\n]+ Match one or more line-break character.
Suppose that i have a table, in which I want to make a column where I count the remaining workdays in a date interval with respect to the current date. An example of such may look like this:
Id Date Start End Remaining
+---+------------+------------+------------+-----+
| 1 | 01-01-2020 | 01-01-2020 | 31-12-2020 | 262 |
+---+------------+------------+------------+-----+
| 1 | 02-01-2020 | 01-01-2020 | 31-12-2020 | 261 |
+---+------------+------------+------------+-----+
| 1 | 03-01-2020 | 01-01-2020 | 31-12-2020 | 260 |
+---+------------+------------+------------+-----+
| 1 | 04-01-2020 | 01-01-2020 | 31-12-2020 | 260 | <--- Weekend
+---+------------+------------+------------+-----+
| 1 | 05-01-2020 | 01-01-2020 | 31-12-2020 | 260 | <--- Weekend
+---+------------+------------+------------+-----+
| 1 | 06-01-2020 | 01-01-2020 | 31-12-2020 | 259 |
+---+------------+------------+------------+-----+
| 1 | 07-01-2020 | 01-01-2020 | 31-12-2020 | 258 |
+---+------------+------------+------------+-----+
Here, I have a date column and the respective start/end dates. As you can see, optimally, I want the countdown to stop, whenever I hit a weekend, similar to the above example.
Additionally, I want to do it in a way, so that I respect individual Ids... That is, I have different Ids with different start and end dates, further down the table.
Currently, I have a hard time figuring out how to make the countdown stop. As of now, I have tried the following DAX formula:
Sum_without_weekends = CALCULATE(COUNTROWS('Table'),
FILTER('Table'(SWITCH(WEEKDAY([Date]),1,0,7,0,1) <> 0) && ('Table'[Id]=EARLIER('Table'[Id]))))
+ IF((SWITCH(WEEKDAY('Table'[Date]),1,0,7,0,1) <> 0),DATEDIFF('Table'[Date],'Table'[Start].[Date],DAY), 0)
This does however yield something along the lines of this, which is wrong:
Id Date StartDate EndDate Remaining
+---+------------+------------+------------+-----+
| 1 | 01-01-2020 | 01-01-2020 | 31-12-2020 | 262 |
+---+------------+------------+------------+-----+
| 1 | 02-01-2020 | 01-01-2020 | 31-12-2020 | 261 |
+---+------------+------------+------------+-----+
| 1 | 03-01-2020 | 01-01-2020 | 31-12-2020 | 260 |
+---+------------+------------+------------+-----+
| 1 | 04-01-2020 | 01-01-2020 | 31-12-2020 | 262 | <--- Weekend
+---+------------+------------+------------+-----+
| 1 | 05-01-2020 | 01-01-2020 | 31-12-2020 | 262 | <--- Weekend
+---+------------+------------+------------+-----+
| 1 | 06-01-2020 | 01-01-2020 | 31-12-2020 | 257 |
+---+------------+------------+------------+-----+
| 1 | 07-01-2020 | 01-01-2020 | 31-12-2020 | 256 |
+---+------------+------------+------------+-----+
Therefore, I need help finishing the DAX formula, in order to make the countdown stop when I hit a weekend, similar to what is visualized in the first table.
Perhaps something like this:
Remaining Working Days =
VAR ID1 = Table1[ID]
VAR Date1 = Table1[Date]
VAR Work_Days = CALCULATE(COUNTROWS(Table1),FILTER(Table1,Table1[ID]=ID1),FILTER(Table1,WEEKDAY(Table1[Date]) in {2,3,4,5,6}),FILTER(Table1,Table1[Date]>=Date1))
RETURN Work_Days
The above calculation uses just the "Date" variable to get the desired result. The idea is to count all working days after the current date and applying a filter for ID as well. Hope this helps.
Is there an easy way to transpose my variables in Stata?
From:
-.48685038 -.13912173 -.91550094 -.96246505
-1.4760038 1.2873173 -.22300169 .25329232
-.01091149 -.58777297 .49454963 2.2842488
-.01376025 -.03060045 -.26231077 .32238093
.51557881 -2.1968436 .36612388 -.40590465
To:
-.48685038 -1.4760038 -.01091149 -.01376025 .51557881
-.13912173 1.2873173 -.58777297 -.03060045 -2.1968436
-.91550094 -.22300169 .49454963 -.26231077 .36612388
-.96246505 .25329232 2.2842488 .32238093 -.40590465
My understanding is that I have to create a matrix first:
mkmat *, matrix(data)
matrix data = data'
svmat data
Try xpose:
. webuse xposexmpl, clear
. list
+--------------------------------+
| county year1 year2 year3 |
|--------------------------------|
1. | 1 57.2 11.3 19.5 |
2. | 2 12.5 8.2 28.9 |
3. | 3 18 14.2 33.2 |
+--------------------------------+
. xpose, clear varname
. list
+-------------------------------+
| v1 v2 v3 _varname |
|-------------------------------|
1. | 1 2 3 county |
2. | 57.2 12.5 18 year1 |
3. | 11.3 8.2 14.2 year2 |
4. | 19.5 28.9 33.2 year3 |
+-------------------------------+
I am having a hard time getting the following measure to work. I am trying to change the target based on a date filter. My filter is the Workday columns, where Workday is a standard date column. sMonth is a month columns formatted as whole number. I am looking to keep the slicer granular, in order to work by day, adding custom columns with month and year and basing the measure on those would help. This is what I have tried and couldn't get it to work:
Cars Inspected =
VAR
selectedMonth = MONTH(SELECTEDVALUE('All Cars Inspected'[Workday]))
RETURN CALCULATE(SUM(Targets[Target]),
FILTER(Targets,Targets[Location]="Texas"),
FILTER(Targets,Targets[Description]="CarsInspected"),
FILTER(Targets,Targets[sMonth]=selectedMonth))
I would appreciate if someone would suggest a different way of achieving the same result.
LE:
This is a mock-up of what I am trying to achieve:
The total cars get filtered by the Workday. I would like to make the Targets/Ranges dynamic. When the slider gets adjusted everything else is adjusted.
My tables look like this:
+-----------+--------------------+----------+
| Workday | TotalCarsInspected | Location |
+-----------+--------------------+----------+
| 4/4/2017 | 1 | Texas |
| 4/11/2017 | 149 | Texas |
| 4/12/2017 | 129 | Texas |
| 4/13/2017 | 201 | Texas |
| 4/14/2017 | 4 | Texas |
| 4/15/2017 | 6 | Texas |
+-----------+--------------------+----------+
+----------+--------+----------+---------------+--------+-----+--------+
| TargetID | sMonth | Location | Description | Target | Red | Yellow |
+----------+--------+----------+---------------+--------+-----+--------+
| 495 | 1 | Texas | CarsInspected | 3636 | 0.5 | 0.75 |
| 496 | 2 | Texas | CarsInspected | 4148 | 0.5 | 0.75 |
| 497 | 3 | Texas | CarsInspected | 4861 | 0.5 | 0.75 |
| 498 | 4 | Texas | CarsInspected | 4938 | 0.5 | 0.75 |
| 499 | 5 | Texas | CarsInspected | 5094 | 0.5 | 0.75 |
| 500 | 6 | Texas | CarsInspected | 5044 | 0.5 | 0.75 |
| 501 | 7 | Texas | CarsInspected | 5043 | 0.5 | 0.75 |
| 502 | 8 | Texas | CarsInspected | 4229 | 0.5 | 0.75 |
| 503 | 9 | Texas | CarsInspected | 4311 | 0.5 | 0.75 |
| 504 | 10 | Texas | CarsInspected | 4152 | 0.5 | 0.75 |
| 505 | 11 | Texas | CarsInspected | 3592 | 0.5 | 0.75 |
| 506 | 12 | Texas | CarsInspected | 3748 | 0.5 | 0.75 |
+----------+--------+----------+---------------+--------+-----+--------+
Let the Value for your gauge be the sum of TotalCarsInspected and set the Maximum value to the following measure:
Cars Inspected =
VAR selectedMonth = MONTH(MAX('All Cars Inspected'[Workday]))
RETURN LOOKUPVALUE(Targets[Target],
Targets[Location], "Texas",
Targets[Description], "CarsInspected",
Targets[sMonth], selectedMonth)