R:如何在LOOP中填充不同尺寸的一个列矩阵?

时间:2015-10-28 11:44:46

标签: arrays r list matrix fill

我已经问了一个类似的question,但是输入数据有不同的维度,我不会让较大的数组填充较小的矩阵或数组。这里显示了我的结构的一些基本示例数据:

dfList <- list(data.frame(CNTRY = c("B", "C", "D"), Value=c(3,1,4)),
               data.frame(CNTRY = c("A", "B", "E"),Value=c(3,5,15)))
names(dfList) <- c("111.2000", "112.2000")

输入数据是&gt; 1000 dfs的列表。我把它变成了一个矩阵列表,第一列是rownames。这里:

dfMATRIX <- lapply(dfList, function(x) {
  m <- as.matrix(x[,-1])
  rownames(m) <- x[,1]
  colnames(m) <- "Value"
  m
})

我试图填充数组的矩阵列表,如 my former question 中所示。这里:

loadandinstall("abind")
CNTRY <- c("A", "B", "C", "D", "E")
full_dflist <- array(dim=c(length(CNTRY),1,length(dfMATRIX)))
dimnames(full_dflist) <- list(CNTRY, "Value", names(dfMATRIX))

for(i in seq_along(dfMATRIX)){
  afill(full_dflist[, , i], local= TRUE ) <- dfMATRIX[[i]]   
}

给出了错误消息:

Error in `afill<-.default`(`*tmp*`, local = TRUE, value = c(3, 1, 4)) : 
  does not make sense to have more dims in value than x

有什么想法吗? 我也像以前的问题一样尝试使用acastarray()而不是dfMATRIX <- lapply...命令。我会假设我的full_dflist - 数组的第二维(抱歉命名:))是错误的,但我不知道如何写输入。我非常感谢你的想法。

编辑2:抱歉,我输错了输出:)这是我新的预期输出:

$`111.2000`
  Value
A    NA
B     3
C     1
D     4
E    NA

$`112.2000`
  Value
A     3
B     5
C    NA
D    NA
E    15

1 个答案:

答案 0 :(得分:2)

这可能是使用data.table的一种解决方案:

library(data.table)
#create a big data.table with all the elements
biglist <- rbindlist(dfList)
#use lapply to operate on individual dfs
lapply(dfList, function(x) {
  #use the big data table to merge to each one of the element dfs
  temp <- merge(biglist[, list(CNTRY)], x, by='CNTRY', all.x=TRUE)
  #remove the duplicate values
  temp <- temp[!duplicated(temp), ] 
  #convert CNTRY to character and set the order on it
  temp[, CNTRY := as.character(CNTRY)]
  setorder(temp, 'CNTRY')
  temp
  })

输出:

$`111.2000`
   CNTRY Value
1:     A    NA
2:     B     3
3:     C     1
4:     D     4
5:     E    NA

$`112.2000`
   CNTRY Value
1:     A     3
2:     B     5
3:     C    NA
4:     D    NA
5:     E    15

编辑

您可以执行以下更新输出:

lapply(dfList, function(x) {
  temp <- merge(biglist[, list(CNTRY)], x, by='CNTRY', all.x=TRUE)
  temp <- temp[!duplicated(temp), ] 
  temp[, CNTRY := as.character(CNTRY)]
  setorder(temp, 'CNTRY')
  data.frame(Value=temp$Value, row.names=temp$CNTRY)
  })

$`111.2000`
  Value
A    NA
B     3
C     1
D     4
E    NA

$`112.2000`
  Value
A     3
B     5
C    NA
D    NA
E    15

但我真的建议使用data.table元素保留列表,而不是转换为data.frames,以便你可以拥有row.names。