【问题标题】:iterating table() results into matrix/data frame将 table() 结果迭代到矩阵/数据框中
【发布时间】:2020-03-27 12:58:52
【问题描述】:

这一定很简单,但我正在用头撞它一会儿。请帮忙。我有一个大型数据集,我通过 table() 从中获取各种信息。然后我想存储这些计数,以及被计算的行名。对于可重现的示例,请考虑

a <- c("a", "b", "c", "d", "a", "b")  # one count, occurring twice for a and 
                                      # b and once for c and d 
b <- c("a", "c")  # a completly different property from the dataset 
                  # occurring once for a and c
x <- table(a)
y <- table(b)  # so now x and y hold the information I seek

我如何合并/绑定/从 x 和 y 获取任何内容到此表单:

   x. y.
a  2. 1
b  2. 0
c  1. 1
d. 1  0

但是,我需要使用该解决方案迭代地工作,在一个循环中使用 x 和 y 并获取上面请求的表单,然后添加更多表,每个表都希望添加一列。为了展示我的(可能有缺陷的)逻辑,我的许多失败尝试之一是:

member <- function (data = dfm, groupvar = 'group', analysis = kc15) {
  res<-matrix(NA,ncol=length(analysis$size)+1) #preparing an object for the results
  res[,1]<-table(docvars(data,groupvar)) #getting names and totals of groups
  for (i in 1:length(analysis$size)) { #getting a bunch of counts that I care about
    r<-table(docvars(data,groupvar)[analysis$cluster==i])
    res<-cbind(res,r) #here's the problem, trying to add each new count as a column.
  }
  res
}

因此,总而言之,上面的可重现示例意味着复制 res 和 r 中的第一列,我正在寻找(我认为)一个正确的解决方案而不是 cbind,这将允许添加不同长度的列但是类似的名称,如上例所示。 请帮我解决一下我在这上面浪费了多少时间

【问题讨论】:

  • 您好,Shouda,该示例无法完全重现,因为我们没有 docvars 函数和 dfm 数据。你能提供这些吗?可能是dput(head(dfm))。请参阅How to make a reproducible example 了解更多信息。

标签: r arrays merge cbind


【解决方案1】:

以下可能是一个选项,它合并从频率表转换而来的数据帧的“行名”:

df <- merge(as.data.frame(x, row.names=1, responseName ="x"), 
            as.data.frame(y, row.names=1, responseName ="y"), 
         by="row.names", all=TRUE)
df[is.na(df)] <- 0; df

  Row.names x y
1         a 2 1
2         b 2 0
3         c 1 1
4         d 1 0

然后,可以通过一些修改将此方法合并到您的真实数据中。因为没有数据,所以我自己编造了。

set.seed(1234)
groupvar <- sample(letters[1:4], 16, TRUE)
clusters <- 1:4
cluster <- rep(clusters, each=4)

合并前两个表:

res <- merge(as.data.frame(table(groupvar[cluster==1]),
                           row.names=1, responseName=clusters[1]),
             as.data.frame(table(groupvar[cluster==2]),
                           row.names=1, responseName=clusters[2]),
             by="row.names", all=TRUE)

然后使用你的 for 循环合并其他人。

for (i in 3:length(clusters)) { 
  r <- table(groupvar[cluster==i])
  res <- merge(res, as.data.frame(r, row.names=1, responseName = clusters[i]), 
               by.x="Row.names", by.y="row.names", all=TRUE)
}
res[is.na(res)] <- 0

res
  Row.names X1 X2 X3 X4
1         a  1  2  0  0
2         b  1  1  2  2
3         c  0  1  1  2
4         d  2  0  1  0

【讨论】:

  • 由于我是盲编码(没有数据),所以有点不稳定,但我认为它可以通过一些调整来工作。
  • 谢谢,我确信它可以,但我自己似乎无法调整它。您的代码给出了“fix.by(by.x, x) 中的错误:'by' 必须指定一个唯一有效的列调用自:fix.by(by.x, x)”。我试图调整它并在控制台中运行每一行,这是:“res
  • 您能否提供上述评论所要求的数据示例?否则很难。编辑您的问题。谢谢。
【解决方案2】:

mergetransposed 并重新转置。

res <- t(merge(t(unclass(x)), t(unclass(y)), all=TRUE))
res <- `colnames<-`(res[order(rownames(res)), 2:1], c("x", "y"))
res[is.na(res)] <- 0
res
#   x y
# a 2 1
# b 2 0
# c 1 1
# d 1 0

【讨论】:

  • 谢谢@jay.sf!它在控制台中适用于 2 个表,但尝试将其放在我的函数中会在 res[order(rownames(res)), 2:1] 中出现错误:下标越界。在第一次迭代中。我还尝试用迭代器 i+1 替换 2:1 中的 2,相同。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多