LoadUI has 2 pools, running and queue. Cap for those pools can be set at project level, also it can be set at each runner level (capped by the project level). Running pool gets filled up as requests get generated by generator. When a response is received, that thread is taken off that pool. But if that pool is filled up (as requests are being generated faster than responses are received), then subsequently generated requests starts going into Queued pool. If running count goes below cap, then requests from Queued gets into running pool. But if Queued pool also gets filled up, then any request generated after that gets discarded. And that's the discarded count.
So basically for your case, 1697 tests ran. Among that 103 failed. But your response times were big enough to make running and queued pools get filled up. So 3000 generated requests got discarded.
To capture request for failed tests, I think, there are 2 ways -
1. Create test case properties. Create property transfer step(s) to capture input and output in the test case. Configure corresponding runner to output testcase properties. Attach output of that runner to a table log. Downside of it is total time taken for that test case will get skewed a bit by few ms taken by property transfer step(s). So if your test case response time is in ms, then it's a big skew, but if it's in few seconds, then ignorable.
2. Use Condition component to detect a failure and output the request data to a table log. I havent yet tried this one. But I think it'll serve the purpose well.