如何在data.table中的嵌套data.table - data.table中进行FAST / ADVANCE数据操作

时间:2018-01-17 16:41:16

标签: r data.table

我在R中有一个名为route_data的data.table。我需要为leg_data的每一行创建一个嵌套的data.table route_data,并从{{{}}的每一行中提取信息。 1}}

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 中创建一个嵌套的leg_data,例如在第一行中应该如下所示:

route_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) )

的第1行中的

example_nested_data

route_data

同样,在 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

的第二和第三行

1 个答案:

答案 0 :(得分:0)

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

另一方面,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>

如果route_data

的第3行中的嵌套data.table,我们来看看里面是什么
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

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))]

我们在这做什么?

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

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

双括号确保它将值作为向量而不是data.table

返回

最后,让我们来看看leg_data第3行的嵌套data.table route_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