【问题标题】:Create list of dataframes based on parent variable names根据父变量名称创建数据框列表
【发布时间】:2018-04-19 21:40:13
【问题描述】:

我正在尝试获取一个数据框并将其转换为包含特定列的数据框列表。

dfs <- data.frame(c('apple', 'apple', 'apple', 'apple'), c('pear','pear','pear','pear'),c('5.30','5.50','5.12','5.63'),c('2.12','2.30','2.40','2.13'),c('5.31','5.55','5.20','5.63'),c('2.15','2.35','2.44','2.15'))
names(dfs) <- c('apple','pear','price_apple','price_pear','ask_apple','ask_pear')

> dfs
apple pear price_apple price_pear ask_apple ask_pear
1 apple pear        5.30       2.12      5.31     2.15
2 apple pear        5.50       2.30      5.55     2.35
3 apple pear        5.12       2.40      5.20     2.44
4 apple pear        5.63       2.13      5.63     2.15

最终目标将是一个包含第一项“苹果”和第二项“梨”的列表。价格和要价变量将是它们各自列表元素的数据框中的列。

以下建议仅适用于样本数据,但无法推断到真实数据集:

tmp <- reshape(dfs[-(1:2)], sep="_", direction="long", timevar="fruit", varying=TRUE)
split(tmp, tmp$fruit)

但返回错误:

猜测错误(变化): 无法从名称中猜出时变变量

reshapeLong 中的错误(数据,idvar = idvar,timevar = timevar,varying = varying,: “可变”参数的长度必须相同

【问题讨论】:

  • 您的错误可能是由于 1) 具有不在模式“variable_time”中的变量,因此reshape 无法通过指定的分隔符 (sep="_") 猜测模式。 2)您有一个时间/组存在但另一个不存在的值。 IE。你有 price_apple/pear ask_apple/pear 然后只有 othervar_apple 没有 pear 组。但如果没有失败的数据示例,我只是在猜测如何解决它。

标签: r list dataframe


【解决方案1】:

你可以这样做:

list(
  appledf = dfs[, grep("apple", colnames(dfs))],
  peardf = dfs[, grep("pear", colnames(dfs))]
)

这给了:

[[1]]
  apple price_apple ask_apple
1 apple        5.30      5.31
2 apple        5.50      5.55
3 apple        5.12      5.20
4 apple        5.63      5.63

[[2]]
  pear price_pear ask_pear
1 pear       2.12     2.15
2 pear       2.30     2.35
3 pear       2.40     2.44
4 pear       2.13     2.15

【讨论】:

  • 这几乎是完美的,但我有几百个水果。无论如何要自动创建df?说基于 dfs[,1:200]。谢谢!
  • 我认为 thelatemail 击败了我。 ;)
【解决方案2】:

reshape 到一个长文件然后split:

tmp <- reshape(dfs[-(1:2)], sep="_", direction="long", timevar="fruit", varying=TRUE)
split(tmp, tmp$fruit)
#$apple
#        fruit price  ask id
#1.apple apple  5.30 5.31  1
#2.apple apple  5.50 5.55  2
#3.apple apple  5.12 5.20  3
#4.apple apple  5.63 5.63  4
#
#$pear
#       fruit price  ask id
#1.pear  pear  2.12 2.15  1
#2.pear  pear  2.30 2.35  2
#3.pear  pear  2.40 2.44  3
#4.pear  pear  2.13 2.15  4

可以说,split 甚至不需要进一步分析。

【讨论】:

  • 我不确定我是否理解 timevar="fruit" 部分。这个变量是从哪里来的?它适用于我的样本数据,但不适用于真实数据集。样本如何知道“水果”来自 1:2 列?
  • @Garglesoap - 这是用于输出数据集中第一个变量的名称。在这种情况下,“时间”也可能意味着“组”。您的原始数据中有变量,例如price_[apple/pear] - 本质上是variable.type_[time]variable.type_[group]。您不必设置timevar= - 例如尝试reshape(dfs[-(1:2)], sep="_", direction="long", varying=TRUE),看看它是如何被标记为time 的。
  • 我收到“猜测错误(变化):无法从名称中猜测时变变量。”有什么方法可以给它一个 1:2 colnames 的向量吗?我的想法是它应该在“_”之后匹配
  • @Garglesoap - 据我所知,您的数据中的前两列是不需要的,因为它们只是重复标签。如果你绝对需要它们,你可以这样做 reshape(dfs, sep="_", direction="long", timevar="fruit", varying=-(1:2))varying= 选项仅指定具有模式 variable_time 的所有变量
  • @Garglesoap - 变化参数就在文档中 - ?stats::reshape - “参数”部分的第二个条目。我认为您可能需要让您的示例数据更能代表您的真实数据,以便正确调试。
【解决方案3】:
fnamevec <- c('orange', 'pear')
fruitlist <- list()
for(i in 1:2){
  temp <- dfs[,grep(as.character(fnamevec[i]), colnames(dfs))]
  fruitlist[[i]] <- temp
}

【讨论】:

  • 在这种情况下,迭代实际字符串并因此命名列表可能会很好。 tempas.character 也是不必要的。 for(fruit in fnamevec) fruitlist[[fruit]] = dfs[, grep(fruit, names(dfs))]
  • 非常好!没想到遍历字符串向量
猜你喜欢
  • 1970-01-01
  • 2017-12-10
  • 2020-09-29
  • 1970-01-01
  • 2013-11-16
  • 2022-01-07
  • 2019-11-08
  • 1970-01-01
  • 2016-02-13
相关资源
最近更新 更多