【问题标题】:Turning a data.frame into a single row将 data.frame 变成单行
【发布时间】:2012-09-20 18:15:19
【问题描述】:

我有这些数据:

structure(list(type = c("journal", "all", "similar_age_1m", "similar_age_3m", 
"similar_age_journal_1m", "similar_age_journal_3m"), count = c("13972", 
"754555", "22408", "56213", "508", "1035"), rank = c("13759", 
"754043", "22339", "56074", "459", "947"), pct = c("98.48", "99.93", 
"99.69", "99.75", "90.35", "91.50")), .Names = c("type", "count", 
"rank", "pct"), row.names = c(NA, -6L), class = "data.frame")

我想把它变成一行,列名2:4 以相应类型为前缀。例如journal.count, journal.rank ...最快的方法是什么?出于某种原因,dcastreshape 没有为我做这件事,我的解决方案有点太麻烦了。

【问题讨论】:

  • 我不明白“count”和“rank”从何而来
  • 我已修复并更新了问题。

标签: r plyr reshape


【解决方案1】:

你提到了reshape2,所以这里有一个方法:

library("reshape2")
dcast(melt(dat, id.var="type"), 1~variable+type)

这给了:

  1 count_all count_journal count_similar_age_1m count_similar_age_3m
1 1    754555         13972                22408                56213
  count_similar_age_journal_1m count_similar_age_journal_3m rank_all
1                          508                         1035   754043
  rank_journal rank_similar_age_1m rank_similar_age_3m
1        13759               22339               56074
  rank_similar_age_journal_1m rank_similar_age_journal_3m pct_all pct_journal
1                         459                         947   99.93       98.48
  pct_similar_age_1m pct_similar_age_3m pct_similar_age_journal_1m
1              99.69              99.75                      90.35
  pct_similar_age_journal_3m
1                      91.50

type 和变量用_ 分隔,而不是.

【讨论】:

  • 太棒了!你已经为我解决了一个古老的问题,我永远无法将数据恢复为原始形式,因为公式总是在寻找第三个变量。
  • 这也提供了与请求不同的名称,但 +1 为 OP 提供了 dcast 修复
  • 我知道 Brian Diggs 会有一个重塑答案 :) +1
【解决方案2】:

这是另一种方式:

y <- as.numeric(as.matrix(x[-1])) # flatten the data.frame
names(y) <- as.vector(outer(x[['type']], names(x)[-1], paste, sep='.'))

【讨论】:

  • 如果 OP 不关心结果是否与问题中显示的顺序相同,则此方法有效。
【解决方案3】:

假设您可以为整形添加一个虚拟“时间”变量,您也可以使用基本 R 轻松完成此操作。假设您的 data.frame 被调用:

mydf$id <- 1
(mydfw <- reshape(mydf, direction = "wide", idvar="id", timevar="type"))
#   id count.journal rank.journal pct.journal count.all rank.all pct.all
# 1  1         13972        13759       98.48    754555   754043   99.93
#   count.similar_age_1m rank.similar_age_1m pct.similar_age_1m
# 1                22408               22339              99.69
#   count.similar_age_3m rank.similar_age_3m pct.similar_age_3m
# 1                56213               56074              99.75
#   count.similar_age_journal_1m rank.similar_age_journal_1m
# 1                          508                         459
#   pct.similar_age_journal_1m count.similar_age_journal_3m
# 1                      90.35                         1035
#   rank.similar_age_journal_3m pct.similar_age_journal_3m
# 1                         947                      91.50

如果你想重新排列你的列,清理也不错。

mydfw <- mydfw[, unlist(sapply(names(mydf), grep, names(mydfw)))]

【讨论】:

    【解决方案4】:

    这是使用expand.grid 获取名称的解决方案。

    要获取数据,首先要删除包含名称的第一列的子集。然后,转置并转换为数字。

    > eg <- expand.grid(colnames(x[, -1]), x[, 1])
    > setNames(as.numeric(t(x[, -1])), paste(eg[[2]], eg[[1]], sep="."))
                   journal.count                 journal.rank 
                        13972.00                     13759.00 
                     journal.pct                    all.count 
                           98.48                    754555.00 
                        all.rank                      all.pct 
                       754043.00                        99.93 
            similar_age_1m.count          similar_age_1m.rank 
                        22408.00                     22339.00 
              similar_age_1m.pct         similar_age_3m.count 
                           99.69                     56213.00 
             similar_age_3m.rank           similar_age_3m.pct 
                        56074.00                        99.75 
    similar_age_journal_1m.count  similar_age_journal_1m.rank 
                          508.00                       459.00 
      similar_age_journal_1m.pct similar_age_journal_3m.count 
                           90.35                      1035.00 
     similar_age_journal_3m.rank   similar_age_journal_3m.pct 
                          947.00                        91.50 
    

    【讨论】:

    • 糟糕。我没有意识到你想要一个data.frame
    【解决方案5】:
    #assuming your data is called "test"
    result <- as.data.frame(matrix(t(test[-1]),nrow=1),stringsAsFactors=FALSE)
    names(result) <- as.vector(t(outer(unique(test$type),names(test[-1]),paste,sep=".")))
    
    str(result)
    'data.frame':   1 obs. of  18 variables:
     $ journal.count               : chr "13972"
     $ journal.rank                : chr "13759"
     $ journal.pct                 : chr "98.48"
     $ all.count                   : chr "754555"
     $ all.rank                    : chr "754043"
     $ all.pct                     : chr "99.93"
     $ similar_age_1m.count        : chr "22408"
     $ similar_age_1m.rank         : chr "22339"
     $ similar_age_1m.pct          : chr "99.69"
     $ similar_age_3m.count        : chr "56213"
     $ similar_age_3m.rank         : chr "56074"
     $ similar_age_3m.pct          : chr "99.75"
     $ similar_age_journal_1m.count: chr "508"
     $ similar_age_journal_1m.rank : chr "459"
     $ similar_age_journal_1m.pct  : chr "90.35"
     $ similar_age_journal_3m.count: chr "1035"
     $ similar_age_journal_3m.rank : chr "947"
     $ similar_age_journal_3m.pct  : chr "91.50"
    

    【讨论】:

    • 不错,但名字倒了。
    【解决方案6】:

    假设您的数据框被称为 dat 这是一个解决方案。这有点粗略,可能不是你想要的:

    dat2 <- data.frame(matrix(unlist(lapply(1:nrow(dat), function(i) dat[i, -1])), nrow=1))
    colnames(dat2) <- paste0(rep(dat[, 1], each=ncol(dat)-1), ".", 1:(ncol(dat)-1)) 
    dat2
    

    如果它不必是数据框,这也可以:

    dat3 <- as.numeric(unlist(lapply(1:nrow(dat), function(i) dat[i, -1])))
    names(dat3) <- paste0(rep(dat[, 1], each=ncol(dat)-1), ".", 1:(ncol(dat)-1)) 
    dat3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-06
      • 1970-01-01
      • 2014-11-19
      • 1970-01-01
      相关资源
      最近更新 更多