【问题标题】:R loop or apply for extracting matrices from dataframe or listR循环或申请从数据框或列表中提取矩阵
【发布时间】:2020-01-22 13:36:27
【问题描述】:

我正在使用国家之间的贸易数据,并希望为每个交易的物品创建一个国家/地区矩阵。像这样的问题之前在这里被问过,我正在使用 persons 示例数据,它没有得到回答,我的问题是不同的,因为我不需要这样做多年。 数据

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,我学到了很多东西,解决方案也很有帮助。第一次在这里问,没想到这么快的解决方案! Desired Output matrix per product

【问题讨论】:

  • 对于上面的例子,你想要的输出是什么样的?还有acast是什么?

标签: r loops dataframe matrix extract


【解决方案1】:

你可以这样做:

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

【讨论】:

  • 非常感谢,这几乎就是我所需要的。问题是我想要每个产品,所以这个列表:DE IT USA ARG BRA 作为列和行。从 DE 到 DE 的贸易当然是 0,但我想用这个对角线来填充产品的使用数据。我在示例中通过编辑添加了用法
  • 请参阅this post 将上述每个产品数组转换为显示所有国家/地区的方阵。您可以将0 设置为矩阵中的默认值,而不是NA。另请注意,您需要将上面lapply 函数的最后一行从x 更改为as.matrix(x)。构建好方阵列表后,您可以通过 diag(z) &lt;- usage 之类的方式更新对角线上的使用数据
  • 该帖子中的解决方案要求需要创建一个新矩阵。如何在 apply 函数中执行此操作?还是我首先需要创建一个包含空矩阵的列表,然后用另一个矩阵列表中的值填充该列表?
  • 请查看答案中的更新 - 这有意义吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-06
  • 2021-03-22
  • 2014-11-21
  • 2015-05-04
  • 1970-01-01
  • 2020-06-19
  • 1970-01-01
相关资源
最近更新 更多