根据列表中数据帧的文件名对大列表中的数据进行子集化
Subset data in a large list based on filename of the dataframes in the list
我正在处理一个包含 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 的列表以及相应的测量深度。
我已经为我的问题搜索了合适的答案,但我只找到了按特定值对数据进行子集化的答案,但我想按文件名 进行子集化。
有人知道怎么做吗?
使用正则表达式,您可以识别独特的传感器 un.se
,您可以从 paste
到 new.names
。原始列表 lst
然后可以 split
变成唯一的传感器, ordered
并转换成 data.frame
s.
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:
在正则表达式 .*
中查找任何 "character-until",然后我们从字面上得到 SE
。现在我们在括号 (
)
内使用分组,在这里我们用 \d+
查找一个或多个数字或 d
igit。在第二个 gsub
参数中 \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))
我正在处理一个包含 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 的列表以及相应的测量深度。
我已经为我的问题搜索了合适的答案,但我只找到了按特定值对数据进行子集化的答案,但我想按文件名 进行子集化。
有人知道怎么做吗?
使用正则表达式,您可以识别独特的传感器 un.se
,您可以从 paste
到 new.names
。原始列表 lst
然后可以 split
变成唯一的传感器, ordered
并转换成 data.frame
s.
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:
在正则表达式 .*
中查找任何 "character-until",然后我们从字面上得到 SE
。现在我们在括号 (
)
内使用分组,在这里我们用 \d+
查找一个或多个数字或 d
igit。在第二个 gsub
参数中 \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))