R l oop или подать заявку на извлечение матриц из кадра данных или списка - PullRequest
0 голосов
/ 22 января 2020

Я использую данные о торговле между странами и хотел бы создать матрицу для каждой страны для каждого предмета торговли. Подобный вопрос уже задавался здесь ранее, и я использую эти лиц примерные данные, на которые не было ответа, у меня другой вопрос, так как мне не нужно было бы делать это в течение нескольких лет. ДАННЫЕ

usage <- data.frame(RC=c("DE", "IT", "USA","BRA", "ARG"),
                    Value=c(3,2,4,77,9,2,6,7,5,4),
                    Item = rep(c("Almonds", "Apples"), each=5))
import<- data.frame(RC=c("DE", "IT", "USA"),
                        PC = c("BRA", "ARG"),
                        Item = c("Almonds", "Apples"),
                        Value = c(1,5,3,2,8,3))


Поэтому мне нужно в итоге получить ~ 450 идентичных матриц для разных продуктов, но все в одной матрице со всеми включенными странами (поэтому страны, не торгующие товаром, должны быть включены с нулевым значением в матрицу продуктов). В конечном итоге я также хотел бы заполнить диагональ этих матриц данными об использовании из стран. Я не знаю, если это слишком сложно, но я надеюсь, что это возможно. К сожалению, мой код не работает .....

Любая помощь в правильном направлении будет принята с благодарностью.

Редактировать: Решено @ user2474226. Я заполнил диагонали, добавив данные об использовании в качестве торговых данных перед созданием матриц.

Окончательный код

usage$PC <- usage$RC #Duplicating the country column of usage
import2 <- rbind(import, usage) # adding the usage data to the trade data

import_YI <- split(import2, list(import2$Item))

trade_matrices <-lapply(import_YI, function(d) {
  x <- with(d, tapply(Value, list(RC, PC), sum)); 
  x[is.na(x)] <- 0; 
  x <- as.matrix(x);
  un1 <- unique(sort(c(colnames(x), rownames(x))));
  m2 <- matrix(0, NROW(un1), NROW(un1), dimnames = list(un1, un1));
  m2[rownames(x), colnames(x)] <- x;
  m2
  }
)

Большое спасибо @ user2474226 Я узнал намного больше, и решения оказались очень полезными. Впервые спрашиваю здесь, поэтому не ожидал такого быстрого решения! Желаемая выходная матрица для продукта

1 Ответ

0 голосов
/ 22 января 2020

Вы можете сделать что-то вроде этого:

import_YI <- split(import, list(import$Item))
lapply(import_YI, function(d) {
                     x <- with(d, tapply(Value, list(RC, PC), sum)); 
                     x[is.na(x)] <- 0; 
                     x})
#output
$Almonds
    ARG BRA
DE    0   1
IT    0   8
USA   0   3

$Apples
    ARG BRA
DE    2   0
IT    5   0
USA   3   0

Я преобразую каждый фрейм данных в списке из длинной формы в широкую форму через tapply. Там, где между двумя странами нет торгуемого продукта, я получу NA, который затем заменю на 0.

Обновление : для создания квадратных матриц, включающих все страны в строки и столбцы (используя:

lapply(import_YI, function(d) {
    x <- with(d, tapply(Value, list(RC, PC), sum)); 
    x[is.na(x)] <- 0; 
    x <- as.matrix(x);
    un1 <- unique(sort(c(colnames(x), rownames(x))));
    m2 <- matrix(0, NROW(un1), NROW(un1), dimnames = list(un1, un1));
    m2[rownames(x), colnames(x)] <- x;
    m2}
    )
# output
$Almonds
    ARG BRA DE IT USA
ARG   0   0  0  0   0
BRA   0   0  0  0   0
DE    0   1  0  0   0
IT    0   8  0  0   0
USA   0   3  0  0   0

$Apples
    ARG BRA DE IT USA
ARG   0   0  0  0   0
BRA   0   0  0  0   0
DE    2   0  0  0   0
IT    5   0  0  0   0
USA   3   0  0  0   0
...