Related
R beginner here.
I have created a dataframe (called combined_ts2) based on a dataset I was given.See this link for the dataframe.
Based on the dataframe a made this ts object (find code at bottom of post).
I am supposed to make a plot based on the TS object. I'm thinking this can be achieved with a ts.plot function, but I can't figure out how to use this function.
The result I want is to get a bar graph for capacity and a line graph for fixtures. Does anyone know how to achieve this, and if I can actually achieve this from a ts object?
dput for dataframe
structure(list(week = c(26, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48), capacity = c(45000L,
39000L, 495500L, 855300L, 1318300L, 1301885L, 8211550L, 18515400L,
32282950L, 31568400L, 35410200L, 29867500L, 34809050L, 36420050L,
33960520L, 33987550L, 33465500L, 24599000L, 11597000L, 4553000L,
1375000L, 545000L), fixtures = c(2L, 4L, 12L, 13L, 18L, 29L,
161L, 338L, 393L, 405L, 439L, 386L, 442L, 406L, 413L, 421L, 326L,
180L, 84L, 23L, 6L, 3L)), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -22L))
Time series code
weekly_timeseries <- ts(combined_ts2, start=c(2019,26), frequency = 52)
I have a specific order in which I want to show a number of my blog posts, but I'd also like to display regular blog posts after those selected ones.
So let's say I have posts [1, 7, 35, 36, 48] which I want to go first:
#selected_posts = Post.find([1, 7, 35, 36, 48])
But now I need to query for every other post, excluding those above:
#other_posts = Post.where.not(id: [1, 7, 35, 36, 48])
And now I need to combine those to maintain that order:
Post.find([1, 7, 35, 36, 48]) + Post.where.not(id: [1, 7, 35, 36, 48])
I'm using Postgres. Is it possible to do this in one query?
You can do order by case...
priority_ids = [1, 7, 35, 36, 48]
#all_posts = Post.all.order("CASE WHEN id IN (#{priority_ids.join(',')}) THEN 1 ELSE 2 END")
(thanks to #DeepakMahakale for correction)
I want to be able to query a user's games where their user_id is in the games' move's white_user_ids or black_user_ids. I also want to be able to query a game's users where its move's white_user_ids or black_user_ids correspond to users.
EDIT:
Before I start explaining my question in more detail, I came up with a workaround:
class User < ActiveRecord::Base
def games
Game.where( [ "moves -> 'black_user_ids' #> '?' OR moves -> 'white_user_ids' #> '?'", self.id, self.id ] )
end
end
class Game < ActiveRecord::Base
serialize :moves, HashSerializer
store_accessor :moves, :white_user_ids, :black_user_ids
def users
User.find((self.white_user_ids + self.black_user_ids).uniq)
end
end
Is there anything wrong with creating custom methods with the names I want, instead of writing out has_many ...? If that is a hack and bad, then please keep reading and feel free to answer.
Initial question:
Here is the most basic version of the schema for this question:
User
id
Game
id
moves - jsonb
white_user_ids - integer array
black_user_ids - integer array
I have created an expression index for both user_ids:
execute <<-SQL
CREATE INDEX moves_white_user_ids_on_games ON games USING GIN ((moves->'white_user_ids'));
CREATE INDEX moves_black_user_ids_on_games ON games USING GIN ((moves->'black_user_ids'));
SQL
I don't know how to set up the relationship between users and games. There is clearly some kind of has_many relationship, or maybe even a has_and_belongs_to_many relationship. But I am storing all the data that I would need to make the association in the games table, moves jsonb column.
Examples:
<User id: 1>
<User id: 5>
<User id: 6>
<User id: 11>
<User id: 17>
<User id: 20>
<User id: 23>
<User id: 35>
<User id: 76>
<User id: 89>
<User id: 93>
<Game id: 1, moves: {"black_user_ids"=>[88],
"white_user_ids"=>[23]}>
<Game id: 2, moves: {"black_user_ids"=>[6, 1, 11, 76, 17, 23],
"white_user_ids"=>[93, 89, 1, 35, 20, 5, 6]}>
<Game id: 3, moves: {"black_user_ids"=>[76, 68, 20, 96, 19, 3],
"white_user_ids"=>[82, 48, 29, 37, 20, 74]}>
<Game id: 4, moves: {"black_user_ids"=>[82],
"white_user_ids"=>[74, 16]}>
<Game id: 5, moves: {"black_user_ids"=>[22, 41, 25, 78, 50],
"white_user_ids"=>[24, 10, 99, 26, 1, 4]}>
User associations/scopes:
User.find(1).games would return games [2, 5], any unique game where either black_user_ids or white_user_ids has their user_id.
User.find(1).black_games would return game [2], any game where black_user_ids has their user_id.
User.find(1).white_games would return games [2, 5], any game where white_user_ids has their user_id.
Game associations/scopes:
Game.find(2).users would return users [1, 5, 6, 11, 17, 20, 23, 35, 76, 89, 93], any unique user in its black_user_ids or white_user_ids.
Game.find(3).black_users would return users [3, 19, 20, 68, 76, 96], any user in its black_user_ids.
Game.find(4).white_users would return users [16, 74], any user in its white_user_ids.
You can do this with polymorphic associations.
http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
The moves table would then have id and type black or white. You can then associate that to game and query black moves or white moves.
Score.where(period: ["q1", "q2"]).pluck(:game_id, :home_score, :away_score)
This query returns results like this:
[[57927, 26, 19], [57927, 28, 23],
[57928, 12, 21], [57928, 17, 25],
[57929, 28, 15], [57929, 24, 20]]
How can I sum the :home_score and :away_score results of the same :game_id, to get this
[[57927, 54, 42],
[57928, 29, 46],
[57929, 52, 35]]
Assuming game_id is a foreign key mapping to Game object, try:
Game.joins(:scores).select("#{Game.table_name}.id, SUM(#{Game.table_name}.home_score) AS home_total, SUM(#{Game.table_name}.away_score) AS total_away").group("#{Game.table_name}.id").pluck[:id, :home_total, :away_total]
Couldn't test it, but it should work with single database query.
You need to use the group clause.
Score.where(period: ["q1", "q2"]).group(:game_id)
.select('game_id, sum(home_score) as home_score_sum, sum(away_score) as away_score_sum')
.all.map {|s| [s.game_id, s.home_score_sum, s.away_score_sum]}
I am learning rails from rails tutorial. I got a problem in the Section 11.3.1, the code in the Listing 11.44:
def self.from_users_followed_by(user)
followed_user_ids = user.followed_user_ids.join(', ')
where("user_id IN (?) OR user_id = ?", followed_user_ids, user)
end
will not return user_id in followed_user_ids.
After searching at stackoverflow, I found the solution here, which said that just remove the "join" method and it works for me.
But I am curious about why there is no error when I run RSPEC before remove the "join" method.
In Listing 11.41:
subject { Micropost.from_users_followed_by(user) }
it { should include(own_post) }
it { should include(followed_post) }
If the "join" method will make the SQL statement wrong, why RSPEC passed?
Does anyone have the same problem?
Update 2012.04.03
I used rails console to check the problem.
user = User.first
ids = ids = user.following_users.map(&:id).join(', ')
Which got
User Load (2.6ms) SELECT "users".* FROM "users" INNER JOIN "follows" ON
"follows"."followable_id" = "users"."id" AND "follows"."followable_type" = 'User' WHERE
"follows"."blocked" = 'f' AND "follows"."follower_id" = 1 AND "follows"."follower_type"
= 'User' AND "follows"."followable_type" = 'User'
=> "6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 55, 56, 5"
Then the SQL
Collection.where("user_id IN (?)", ids)
The result is
Collection Load (0.7ms) SELECT "collections".* FROM "collections" WHERE (user_id IN
('6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 55, 56, 5')) ORDER BY collections.created_at DESC
=> []
Which return an empty array.
But I got all my rspec passed. Still no idea.
Assuming the join creates a string '1,2,3', then perhaps you want to join("','") to have ('1','2','3'), but I don't think this will work - I'm sure PostgreSQL doesn't like IDs as strings.
Alternatively:
Squeel is a good SQL syntax gem where you could use:
user = User.first
ids = user.following_users.map(&:id)
Collection.where{(user_id.like_any ids)}
This will allow you to pass in the array of integers and Squeel will setup the query where:
SELECT "collections".* FROM "collections" WHERE (("collections"."user_id" LIKE 1 OR "collections"."user_id" LIKE 2 OR "collections"."user_id" LIKE 3))
EDIT: You can also use the syntax:
ids = User.first.following_users.pluck(:id)
Collection.find_by_user_id(ids)