【问题标题】:Subset data in a large list based on filename of the dataframes in the list根据列表中数据框的文件名在大列表中设置数据子集
【发布时间】:2020-07-10 14:26:04
【问题描述】:

我正在处理一个包含 450 个数据帧的大型列表。我将举例说明数据框的名称

ALL_SM51_SE1_hourly, ALL_SM201_SE1_hourly, ALL_SM501_SE1_hourly
ALL_SM51_SE2_hourly, ALL_SM201_SE2_hourly, ALL_SM501_SE2_hourly
...................................................................
ALL_SM51_SE150_hourly, ALL_SM201_SE150_hourly, ALL_SM501_SE150_hourly

数据框包含在不同深度(5cm、20cm、50cm,在文件名中用“SM51、SM201、SM501”表示)测量的土壤水分数据,并且有150个传感器由文件名中的“SE1、SE2、SE3...”表示)这就是为什么我有 450 个数据帧存储在一个列表中的原因。

我想做什么:我想为每个传感器创建一个新列表(创建一个子集),然后包含 3 个元素。所以我想要一个 SE1、SE2、SE3、...、SE150 的列表以及相应的测量深度。

我已经为我的问题搜索了适当的答案,但我只找到了按特定值对数据进行子集的答案,但我想按文件名进行子集

有人知道怎么做吗?

【问题讨论】:

  • "ALL_SM_201,SE2_hourly" 是不是一个错误,即它实际上是"ALL_SM201_SE2_hourly"
  • @jay.sf 哦,是的,对不起!我改了。

标签: r list subset filenames


【解决方案1】:

使用正则表达式,您可以识别独特的传感器un.se,您可以从pastenew.names。原始列表lst 然后可以将split 转换为唯一的传感器,ordered 并转换为data.frames。

un.se <- gsub(".*SE(\\d+).*", "\\1", names(lst))
new.names <- paste0("SE", unique(un.se))
tmp <- setNames(split(lst, un.se), paste0("SE", unique(un.se)))
res <- lapply(tmp, function(x) {
  nm <- gsub(".*SM(\\d+).*", "\\1", names(x))
  setNames(lapply(x[order(nm)], data.frame), paste0("d", gsub("1$", "", nm)))
  })

解释gsub-regex:

在正则表达式.* 中查找任何“字符-直到”,然后我们就有SE 字面意思。现在我们在括号() 内使用分组,我们用\\d+ 查找一个或多个出现的数字或digit。在第二个 gsub-argument \\1 对第一组(括号中的那个)进行反向引用以替换整个字符串。例如。结果 un.se 是每个字符串中每个 SE 之后的数字(请参阅:https://regex101.com/r/zuO8Ts/1;请注意,我们需要在 R 中使用双重转义 \\)。

这会在子列表中列出每个传感器以及每个深度的数据帧。

结果

res
# $SE1
# $SE1$d5
#   x1 x2 x3
# 1  1  2  3
# 
# $SE1$d20
#   x1 x2 x3
# 1  1  2  3
# 
# $SE1$d50
#   x1 x2 x3
# 1  1  2  3
# 
# 
# $SE2
# $SE2$d5
#   x1 x2 x3
# 1  1  2  3
# 
# $SE2$d20
#   x1 x2 x3
# 1  1  2  3
# 
# $SE2$d50
#   x1 x2 x3
# 1  1  2  3

玩具数据

lst <- list(ALL_SM51_SE1_hourly = list(x1 = 1, x2 = 2, x3 = 3), ALL_SM201_SE1_hourly = list(
    x1 = 1, x2 = 2, x3 = 3), ALL_SM501_SE1_hourly = list(x1 = 1, 
    x2 = 2, x3 = 3), ALL_SM51_SE2_hourly = list(x1 = 1, x2 = 2, 
    x3 = 3), ALL_SM201_SE2_hourly = list(x1 = 1, x2 = 2, x3 = 3), 
    ALL_SM501_SE2_hourly = list(x1 = 1, x2 = 2, x3 = 3))

【讨论】:

  • 哇,成功了。非常感谢您快速而有帮助的回复!你已经做得够多了,但我是 R 新手,这对我来说似乎很先进。你能解释一下你到底做了什么吗?
  • 我特别不明白".*SE(\\d+).*", "\\1"的表达方式。
  • @Phil 添加了一些解释,这有意义吗?
猜你喜欢
  • 1970-01-01
  • 2020-08-19
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2021-10-07
  • 2020-11-21
  • 2019-12-21
相关资源
最近更新 更多