【问题标题】:How to turn variable names into factors in a data frame in R如何将变量名称转换为R中数据框中的因素
【发布时间】:2013-07-18 00:37:56
【问题描述】:

假设我有一个包含时间序列数据的数据框,其中第一列是索引,其余列都包含不同的数据流,并以描述性方式命名,如下例所示:

temps = data.frame(matrix(1:20,nrow=2,ncol=10))
names(temps) <- c("flr1_dirN_areaA","flr1_dirS_areaA","flr1_dirN_areaB","flr1_dirS_areaB","flr2_dirN_areaA","flr2_dirS_areaA","flr2_dirN_areaB","flr2_dirS_areaB","flr3_dirN_areaA","flr3_dirS_areaA")
temps$Index <- as.Date(2013,7,1:2)

temps
  flr1_dirN_areaA flr1_dirS_areaA    ...       Index
1               1               3    ...  1975-07-15
2               2               4    ...  1975-07-16   

现在我想准备数据框以使用 ggplot2 进行绘图,并且我想包括三个因素:flrdirarea

对于这个简单的例子,我可以做到这一点,如下所示:

temps.m <- melt(temps,"Index")
temps.m$flr <- factor(rep(1:3,c(8,8,4)))
temps.m$dir <- factor(rep(c("N","S"),each=2,len=20))
temps.m$area <- factor(rep(c("A","B"),each=4,len=20))
temps.m
        Index        variable value flr dir area
1  1975-07-15 flr1_dirN_areaA     1   1   N    A
2  1975-07-16 flr1_dirN_areaA     2   1   N    A
3  1975-07-15 flr1_dirS_areaA     3   1   S    A
4  1975-07-16 flr1_dirS_areaA     4   1   S    A
5  1975-07-15 flr1_dirN_areaB     5   1   N    B
6  1975-07-16 flr1_dirN_areaB     6   1   N    B
7  1975-07-15 flr1_dirS_areaB     7   1   S    B
8  1975-07-16 flr1_dirS_areaB     8   1   S    B
9  1975-07-15 flr2_dirN_areaA     9   2   N    A
10 1975-07-16 flr2_dirN_areaA    10   2   N    A
11 1975-07-15 flr2_dirS_areaA    11   2   S    A
12 1975-07-16 flr2_dirS_areaA    12   2   S    A
13 1975-07-15 flr2_dirN_areaB    13   2   N    B
14 1975-07-16 flr2_dirN_areaB    14   2   N    B
15 1975-07-15 flr2_dirS_areaB    15   2   S    B
16 1975-07-16 flr2_dirS_areaB    16   2   S    B
17 1975-07-15 flr3_dirN_areaA    17   3   N    A
18 1975-07-16 flr3_dirN_areaA    18   3   N    A
19 1975-07-15 flr3_dirS_areaA    19   3   S    A
20 1975-07-16 flr3_dirS_areaA    20   3   S    A

实际上,我有不同长度的数据流(列) - 每个都来自其自己的文件,缺少数据,列(文件)名称中编码的因子超过 3 个,所以这种简单的应用因子方法不会工作。我需要更健壮的东西,我倾向于将变量名称解析为不同的因子,并填充融合数据框的因子列。

我的最终目标是绘制这样的图:

ggplot(temps.m,aes(x=Index,y=value,color=area,linetype=dir))+geom_line()+facet_grid(flr~.)

我想 reshape、reshape2、plyr 或其他一些包可以在一两个语句中做到这一点 - 但我在使用 melt/cast/ddply 和其他包时遇到了困难。有什么建议么?

此外,如果您能提出一种完全不同的 [更好] 方法来构建我的数据,我会全力以赴。

提前致谢

【问题讨论】:

  • 我认为您需要将问题减少到特定组件,并使用最少的代码使它们可重现。
  • 那里有 8 行代码,前三行提供了我拥有的数据的示例,接下来的 4 行导致重新格式化的数据集(格式化为我需要绘图的结构) ,最后一行创建了一个情节,以显示我的最终目标是什么。我具体可以改进或澄清什么?如果有帮助,我很乐意编辑
  • @RyanStochastic 主要是您有一个具有特定模式的 字符串,并且您想提取/拆分为 3 个或更多因素就是这样。 所以所有其他信息,如情节上下文/情节本身就是令人困惑...
  • @RyanStochastic 尝试重新表述你的问题并专注于字符串模式(见上面的评论),你会得到更好的解决方案。
  • 我添加了情节和上下文,希望得到一个更通用的解决方案,或者关于如何以不同方式解决问题的建议,而不是针对这个特定的、非常简单的数据集量身定制的特定解决方案。我理解您的观点,感谢您的时间和精力。

标签: r dataframe reshape


【解决方案1】:

您可以使用一些正则表达式来创建您的因子:

res <- do.call(rbind,strsplit(gsub('flr([0-9]+).*dir([A-Z]).*area([A-Z])',
              '\\1,\\2,\\3',  
              temps.m$variable),
         ','))

    [,1] [,2] [,3]
 [1,] "1"  "N"  "A" 
 [2,] "1"  "N"  "A" 
 [3,] "1"  "S"  "A" 
 [4,] "1"  "S"  "A" 
 [5,] "1"  "N"  "B" 
 [6,] "1"  "N"  "B" 
 [7,] "1"  "S"  "B" 
 [8,] "1"  "S"  "B" 
 ........

也许您需要进一步将列转换为因子。

res <- colwise(as.factor)(data.frame(res))
  X1 X2 X3
1   1  N  A
2   1  N  A
3   1  S  A
4   1  S  A
........

要将结果与融化的数据结合起来,您可以使用cbind

 temps.m <- cbind(temps.m,res)

【讨论】:

  • 好的,这给了我一个包含 20 个条目的列表,每个条目都以正确的顺序包含正确的因素,然后我如何将它与我的融化数据框 temps.m 结合起来,或者我如何包含ggplot 中的那些因素?
  • 另外,这个例子非常简单。实际的列名并不总是具有相同的结构,可能只有一个或两个因素,可能有五个或六个 - 因此首选更通用的解决方案
  • @RyanStochastic 您在问题中哪里提到了这一点?我想,我回答了被问到的问题。
  • 我确实提到了“超过 3 个因素”,但确实您已经解决了提供的简单示例。如果列名中有不同的因素,您将如何更改?例如flr1_AreaB,flr1_AreaB_type5,dirN_AreaB,flr1,AreaB
  • ...目前我的方法是为每个可能的因素设置一行,每行都有一个 gsub 命令,你的更优雅,因为它一次完成三个,我只是想也许某些包中内置了一些东西
【解决方案2】:

这是一种将一堆格式正确的字符串转换为因子变量数据框的方法。这假设因子被_ 分割,并且每个子字符串中的最后一个字符是所需的级别。

require(plyr)

v <- do.call(rbind, strsplit(as.character(temps.m$variable), "_"))

v <- alply(v, 2, function(x) {
    n <- nchar(x)
    name <- substr(x, 1, n - 1)[1]
    lev <- substr(x, n, n)
    structure(factor(lev), name=name)
})

names(v) <- sapply(v, attr, "name")

temps.m <- cbind(temps.m, as.data.frame(v))

添加更多通用性留给读者作为练习。

【讨论】:

  • 洪,谢谢你的回答;这也有效,并且对于_ 分隔每个级别并且级别都具有单字符定义的情况更为通用,但是我的数据中的某些级别从 1 到 25,并且下划线分隔符是' 不是可靠的分隔符(有时级别根本不分隔,有时由空格分隔)。正如 agstudy 提到的,我应该在我的问题中更具体。我现在要关闭这个,并且可能会发布一个更“通用”的问题,以获得我正在寻找的答案。
猜你喜欢
  • 2020-01-01
  • 1970-01-01
  • 2022-10-13
  • 1970-01-01
  • 1970-01-01
  • 2021-01-21
  • 1970-01-01
  • 1970-01-01
  • 2016-03-07
相关资源
最近更新 更多