У меня есть таблица buildings
с 3,2 миллионами строк. Мне нужно расширить эту таблицу до 11 различных периодов, чтобы обрабатывать ее как (сбалансированные) Paneldata. Это означает, что для каждого объекта есть 11 разных лет (с 2000 по 2010 год) для наблюдения. Периоды следует называть:
2000
2001
...
2009
2010
ОПРЕДЕЛЕНИЯ ТАБЛИЦ
CREATE TABLE public.buildings
(
gid integer NOT NULL DEFAULT nextval('buildings_gid_seq'::regclass),
osm_id character varying(11),
name character varying(48),
type character varying(16),
geom geometry(MultiPolygon,4326),
centroid geometry(Point,4326),
gembez character varying(50),
gemname character varying(50),
krsbez character varying(50),
krsname character varying(50),
pv boolean,
gr smallint,
capac double precision,
instdate date,
pvid integer,
dist double precision,
gemewz integer,
n500 integer,
ibase double precision,
popden integer,
instp smallint,
b2000 double precision,
b2001 double precision,
b2002 double precision,
b2003 double precision,
b2004 double precision,
b2005 double precision,
b2006 double precision,
b2007 double precision,
b2008 double precision,
b2009 double precision,
b2010 double precision,
ibase_id integer[],
ibase_dist integer[],
CONSTRAINT buildings_pkey PRIMARY KEY (gid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.buildings
OWNER TO postgres;
CREATE INDEX build_centroid_gix
ON public.buildings
USING gist
(st_transform(centroid, 31467));
CREATE INDEX buildings_geom_idx
ON public.buildings
USING gist
(geom);
Я хочу использовать данные для регрессионного анализа в R.
ibase_id
представляет собой массив gid
. ibase_dist
— связанный массив с расстояниями от gid
до объекта. Длина двух массивов всегда одинакова.
gid
в массиве принадлежат записям buildings
, которые находятся в радиусе 500 м вокруг centroid
, центра объекта, и имеют pv=TRUE (что означает, что dist
,instdate
,instp
,capac
&pvid
равны NOT NULL
).
SELECT a.gid AS buildid, array_agg(b.gid) AS ibase_id, array_agg(round(ST_Distance(ST_Transform(a.centroid, 31467), ST_Transform(b.centroid, 31467))::integer)) AS ibase_dist
FROM buildings a
LEFT JOIN (SELECT * FROM buildings WHERE pv=TRUE) AS b ON ST_DWithin(ST_Transform(a.centroid, 31467), ST_Transform(b.centroid, 31467), 500.0)
AND a.gid <> b.gid
GROUP BY a.gid
Пример:
ibase_id: {3075528,409073,322311,226643,833798,322344,226609}
;
ibase_dist {290,293,398,494,411,381,384}
UPDATE buildings
SET ibase=SUM(1/s)
FROM unnest(SELECT ibasedist FROM buildings WHERE (SELECT instp
FROM buildings
WHERE gid IN unnest(ibase_id))<year) s
Для каждого периода учитываются только записи массивов, чьи годы были ДО наблюдаемого периода панельных данных. (Приведенный выше запрос пока не работает, потому что мне нужно сначала объединить массивы) Сейчас два массива содержат информацию за все годы. Вот почему я подумал, что их нужно добавлять к каждому периоду времени, чтобы после расширения до панельных данных я вычислял ibase
для каждой записи (11x 3,2 миллиона).
Мне не нужны все столбцы для регрессионного анализа. В случае, если это значительно улучшит производительность умножения, мы могли бы придерживаться строк (в основном исключая столбцы геометрии):
gid integer NOT NULL DEFAULT nextval('buildings_gid_seq'::regclass),
gembez character varying(50),
gemname character varying(50),
krsbez character varying(50),
krsname character varying(50),
pv boolean,
gr smallint,
capac double precision,
dist double precision,
gemewz integer,
n500 integer,
ibase double precision,
popden integer,
instp smallint,
b2000 double precision,
b2001 double precision,
b2002 double precision,
b2003 double precision,
b2004 double precision,
b2005 double precision,
b2006 double precision,
b2007 double precision,
b2008 double precision,
b2009 double precision,
b2010 double precision,
ibase_id integer[],
ibase_dist integer[],
CONSTRAINT buildings_pkey PRIMARY KEY (gid)
)
WITH (
OIDS=FALSE
Подход к решению
У меня была основная идея создать вторую таблицу periods
, содержащую 11 разных периодов, и умножить эту таблицу на таблицу buildings
. Не уверен, как это реализовать. К сожалению, у меня мало опыта работы с R, и я не использую базу данных. Интерфейса для R пока нет.
Работа с PostgreSQL 9.5beta2, скомпилированным Visual C++ build 1800, 64-bit и R x64 3.2.1
RPostgreSQL
и запрашивайте только те столбцы, которые вам нужны, с помощьюdbGetQuery
. Позже манипулируйте с пакетом Rdata.table
, его синтаксис очень похож на SQL, но гораздо более модульный и быстрый, поскольку он вписывается в память и хорошо написан на C. Вы можете перекрестно соединить свою таблицу с таблицей периодов, чтобы сделать взрыв строки. - person jangorecki   schedule 07.02.2016