The right-fielder hit an RBI single in the top of the fourth inning and added a two-run homer in the ninth.
Kansas City's Mark Grudzielanek had two hits and one RBI.
Mike Aviles also had two hits in the Royals' fifth win in a row.
Winner Zach Greinke (6-4) gave up an earned run and just two hits in seven innings with a walk and seven strikeouts, while closer Joakim Soria recorded his 18th save this season with a 1-2-3 ninth.
St. Louis scored its only run on Rick Ankiel's solo homer in the bottom of the fourth.
Aaron Miles had the other hit for the Cardinals, who lost for the fourth time in their last six games.
Losing pitcher Brad Thompson (1-2) allowed two earned runs and five hits in five innings.