有没有办法在tbl中使用reshape?

问题描述 投票:0回答:2

在上一个问题中,我在使用重塑时遇到了问题:

重塑错误 - 无效的“row.names”长度

几个小时后我意识到这是因为我使用的是 tbl 格式而不是 data.frame。因此,要使用 reshape 并保持 tbl 环境,我必须这样做:

mydata %>% as.data.frame %>% reshape(, ...) %>% as.tbl

所以我想知道是否还有其他方法可以做到这一点。

r dataframe dplyr reshape
2个回答
1
投票

为了比任何其他原因都有答案,这里有四个选项需要考虑。

首先,如果您想将

reshape
与“dplyr”一起使用,则必须使用
new.row.names
中的
reshape
参数,并将它们设置为您期望重塑的行数序列拥有的数据集。计算很容易。取一批从宽形式变为长形式的列的长度,并将其乘以原始数据集中的行数。

这种方法肯定会让 Hadley 感到不安,所以使用风险自负。

mydf <- tbl_df(mydf)
class(mydf)
# [1] "tbl_df"     "tbl"        "data.frame"

mydf %>% 
  reshape(
    idvar="g_id",
    direction="long",
    varying=list(c(5:14),c(15:24)), 
    v.names=c("PLC","P"),
    new.row.names = seq_len(length(5:14) * nrow(mydf)))

另一种可能让哈德利局促不安但稍微少一点的方法是使用

melt
,但
melt
来自“data.table”,而不是来自“reshape2”。当然,这需要您将
tbl_df
转换为
data.table
,与您当前的方法类似,它需要另一个步骤。

library(data.table)
mydf %>%
  data.table %>%
  melt(measure.vars = patterns("PLC[0-9]+", "P[0-9]+"), 
       value.name = c("PLC", "P"))

留在 Hadleyverse 中,您可以尝试“tidyr”(如@DavidArenburg 的建议)。它并不像他想象的那么漂亮,因为它需要首先制作一个very长的数据集,然后重新扩展它,这与上面的

melt
方法不同,它一步完成了不太长的重塑。

library(tidyr)
mydf %>%
  gather(var, val, starts_with("P")) %>%
  mutate(var = gsub("([A-Z]+)", "\\1_", var)) %>%  ## you can probably be clever and...
  separate(var, into = c("variable", "time")) %>%  ## come up with some fancier regex
  spread(variable, val)

最后,还有我的“splitstackshape”包中的

merged.stack
。有了它,方法将是这样的:

library(splitstackshape)
merged.stack(mydf, var.stubs = c("PLC", "P"), sep = "var.stubs")

0
投票

如果我们真的想这样做,另一种选择可能是

quickdf(mydf) |> 
  reshape( ... ... )

哪里

quickdf = \(l) { 
  class(l) = "data.frame"; attr(l, "row.names") = .set_row_names(length(l[[1L]])); l 
}

来自这里

© www.soinside.com 2019 - 2024. All rights reserved.