r - 如何在 data.table 中的嵌套 data.table 中进行快速/高级数据操作



我在R中有一个名为route_data的data.table。我需要创建一个嵌套的 data.tableleg_data到每一行route_data,其中包含从每行中提取的信息route_data

route_data <- data.table(route = c("Seattle>NewDelhi>Patna>Motihari", "Seattle>NewDelhi>Motihari","Seattle>Hyderabad>NewDelhi>Patna>Motihari"),
travel_type = c("business_meeting", "casual_trip","office_meeting"), 
leg1_time_hr = c(18.0,18.0,18.0),
leg2_time_hr = c(2,18,2.25),
leg3_time_hr = c(4.0,NA,1.75),
leg4_time_hr = c(NA,NA,4.0))

route_data

route                           travel_type          leg1_time_hr  leg2_time_hr leg3_time_hr leg4_time_hr
1:           Seattle>NewDelhi>Patna>Motihari business_meeting           18         2.00         4.00           NA
2:                 Seattle>NewDelhi>Motihari      casual_trip           18        18.00           NA           NA
3: Seattle>Hyderabad>NewDelhi>Patna>Motihari   office_meeting           18         2.25         1.75            4

我需要在route_data中创建一个嵌套leg_data,例如在第一行中,它应该如下所示:

example_nested_data <- data.table(leg = c("Seattle>Hyderabad", "Hyderabad>NewDelhi","NewDelhi>Patna","Patna>Motihari"),
leg_num = c(1,2,3,4), 
leg_transit_time_hr = c(18.0,2.25,1.75,4.0)
)

example_nested_dataroute_data的第 1 行中

leg                  leg_num           leg_transit_time_hr
1:  Seattle>Hyderabad       1               18.00
2: Hyderabad>NewDelhi       2                2.25
3:     NewDelhi>Patna       3                1.75
4:     Patna>Motihari       4                4.00

同样,在第二行和第三排route_data

我将尝试自己回答。我看到警告消息,希望更好地理解它的任何限制。但是,对我来说它工作正常(忽略警告消息)。

附带说明一下,data.table打破了R的所有限制,阻止它进行大数据处理,以免我忘记我自己的研究希望它被记录下来。

同时,让我们创建一个函数,将路由分解为腿:

construct.legs <- function(ro) {
node_vector <- unlist(strsplit(ro, ">"))
d_nodes <- node_vector[!node_vector %in% node_vector[1]]
o_nodes <- node_vector[!node_vector %in% node_vector[length(node_vector)]]
legs <- paste(o_nodes,d_nodes, sep = ">")
}

现在,为包含路由段的每个路由创建嵌套leg_table。当然,使用上面定义的函数construct.legs

route_data[, leg_data := .(list(data.table(leg = construct.legs(route)))), by = list(row.names(route_data))]

我们现在的route_data是什么样子的?

route      travel_type leg1_time_hr leg2_time_hr leg3_time_hr leg4_time_hr     leg_data
1:           Seattle>NewDelhi>Patna>Motihari business_meeting           18         2.00         4.00           NA <data.table>
2:                 Seattle>NewDelhi>Motihari      casual_trip           18        18.00           NA           NA <data.table>
3: Seattle>Hyderabad>NewDelhi>Patna>Motihari   office_meeting           18         2.25         1.75            4 <data.table>

让我们来看看如果嵌套的 data.table 在第三行中route_data里面有什么

route_data$leg_data[3]  #Access the leg_table like we do in data.frame. But this returns leg_data as a list
route_data$leg_data[[3]]  #This returns leg_data as a data.table
route_data[3, leg_data] #Access the leg_table like we do in data.table. This returns leg_data as a list
route_data[3, leg_data[[1]]] #This returns leg_data as a data.table

数据表存储在route_data的第 3 行

leg
1:  Seattle>Hyderabad
2: Hyderabad>NewDelhi
3:     NewDelhi>Patna
4:     Patna>Motihari

让我在route_data中添加行号,稍后我将在嵌套表leg_data填充传输时间时使用

route_data[, route_num := seq_len(.N)]

同样,在嵌套表中添加行号leg_Table

route_data[, leg_data := .(list(leg_data[[1]][, leg_num := seq_len(.N)])), by = list(row.names(route_data))]

您会看到一条警告消息,指出存在无效的内部自引用,该自引用已通过浅层复制修复。所以,我现在将忽略这一点。我需要有人的帮助,他可以帮助我了解它是否破坏了任何东西。无论如何,让我们继续。

为什么我们有[[1]]?这是为了确保sub_table值以 data.table 的形式返回,而不是作为列表返回。尝试运行route_data[3, leg_data[[1]]]route_data[3, leg_data]以查看差异。

现在终于在嵌套leg_data中添加传输时间route_data

route_data[, leg_data := .(list(leg_data[[1]][, leg_transit_time_hr := sapply(leg_num, function(x) {route_data[[route_num, 2+x, with = FALSE]]})])), by = list(row.names(route_data))]

我们在这里做了什么?

我们只是通过sapply将其作为向量传递来循环leg_data的行号leg_num,并利用route_data的行号route_num来识别要从route_data中提取的传输时间的右列。

为什么我们在[[route_num, 2+x, with = FALSE]]上放置双[[]]

双大括号确保它返回的值作为向量而不是 data.table

最后,让我们看一下第 3 行route_data的嵌套 data.tableleg_data

route_data[3, leg_data[[1]]]
leg             leg_num       leg_transit_time_hr
1:  Seattle>Hyderabad       1               18.00
2: Hyderabad>NewDelhi       2                2.25
3:     NewDelhi>Patna       3                1.75
4:     Patna>Motihari       4                4.00

让我们看看第二行嵌套表的样子:

leg            leg_num       leg_transit_time_hr
1:  Seattle>NewDelhi       1                  18
2: NewDelhi>Motihari       2                  18

最新更新