【问题标题】:For each item in Dataframe want to loop automatically对于 Dataframe 中的每个项目都想自动循环
【发布时间】:2019-07-03 09:17:26
【问题描述】:

我不想重塑它,因为我有很多数据,所以像循环这样的东西会自动翻译它 输入 - 数据框 1

Item     LC     ToLC
8T4121  MW92    WK14
8T4121  WK14    RM11
8T4121  WK14    RS11
8T4121  RS11    OY01
AB7651  MW92    RS11
AB7651  RS11    OY01

我想做一个循环,我可以得到这样的输出 数据框 2

Item     LC1    LC2    LC3    LC4
8T4121  MW92    WK14   RM11  
8T4121  MW92    WK14   RS11   OY01
AB7651  MW92    RS11   OY01

我尝试过这样的事情:

bodlane <- lctolc
colnames(bodlane) <- c("Item","Entry","From")

bodlane$To <- lctolc$To[match(bodlane$From, lctolc$From)]
colnames(bodlane) <- c("Item","Entry","Parent","From")

bodlane$To <- lctolc$To[match(bodlane$From, lctolc$From)]
colnames(bodlane) <- c("Item","Entry","Parent","Parent1","From")

bodlane$To <- lctolc$To[match(bodlane$From, lctolc$From)]
colnames(bodlane) <- c("Item","LC","ToLC","Parent1","From","To")

【问题讨论】:

  • 不想重塑它
  • 您如何获得预期的输出?您是否每两行分组一次?
  • 请尝试更清楚地解释您希望如何获得预期的输出
  • 基本上,ToLC 列中的值应该是搜索 LC 列中的值,并在 LC 之间建立进一步的关系

标签: r function loops


【解决方案1】:

我相信这可以通过igraph 以与“recursive” self join in data.table 类似的方式解决,但无需计算。

这里的困难在于每个Item 都有单独的图表。我的方法是将数据框拆分为图表列表。可能有更简洁的解决方案使用type 顶点属性。

但是,下面的代码会产生预期的结果:

library(igraph)
library(data.table)
library(magrittr)
       
lapply(
  lapply(split(lctolc, lctolc$Item), function(x) graph.data.frame(x[, 2:3])), 
  function(x) lapply(
    V(x)[degree(x, mode = "in") == 0], 
    function(s) all_simple_paths(x, from = s, 
                                 to = V(x)[degree(x, mode = "out") == 0]) %>% 
      lapply(
        function(y) as.data.table(t(names(y))) %>% setnames(paste0("LC", seq_along(.)))
      ) %>% 
      rbindlist(fill = TRUE) 
  ) %>% rbindlist(fill = TRUE)
) %>% rbindlist(fill = TRUE, idcol = "Item")
     Item  LC1  LC2  LC3  LC4
1: 8T4121 MN12 AB12 BC34 <NA>
2: 8T4121 MW92 WK14 RS11 OY01
3: 8T4121 MW92 WK14 RM11 <NA>
4: AB7651 MW92 RS11 OY01 <NA>

说明

igraph 包是解决此类问题的不错选择。

但是,我们需要分别处理每个Item 的图。这是通过拆分 data.frame 并通过

创建图表列表来实现的
lg <- lapply(split(lctolc, lctolc$Item), function(x) graph.data.frame(x[, 2:3]))

返回

lg
$`8T4121`
IGRAPH 8eb2bcc DN-- 8 6 -- 
+ attr: name (v/c)
+ edges from 8eb2bcc (vertex names):
[1] AB12->BC34 MN12->AB12 MW92->WK14 WK14->RM11 WK14->RS11 RS11->OY01

$AB7651
IGRAPH 7cd75e7 DN-- 3 2 -- 
+ attr: name (v/c)
+ edges from 7cd75e7 (vertex names):
[1] MW92->RS11 RS11->OY01

或者,通过两个单独的图进行可视化。

lapply(seq_along(lg), function(i) plot(lg[[i]], main = names(lg)[i]))

现在,函数all_simple_paths() 列出了从一个源顶点到另一个顶点的简单路径,或者如果顶点被访问一次,则路径是简单的顶点。要使用该功能,我们需要确定起始节点和所有结束节点。这是通过

实现的
V(x)[degree(x, mode = "in") == 0]  # start nodes
V(x)[degree(x, mode = "out") == 0] # end nodes 

degree() 函数分别返回传入或传出边的数量。

对于我们的示例数据集,我们得到

lapply(lg, function(x) V(x)[degree(x, mode = "in") == 0]) # start nodes
$`8T4121`
+ 2/8 vertices, named, from 8eb2bcc:
[1] MN12 MW92

$AB7651
+ 1/3 vertex, named, from 7cd75e7:
[1] MW92
lapply(lg, function(x) V(x)[degree(x, mode = "out") == 0]) # end nodes
$`8T4121`
+ 3/8 vertices, named, from 8eb2bcc:
[1] BC34 RM11 OY01

$AB7651
+ 1/3 vertex, named, from 7cd75e7:
[1] OY01

现在,我们遍历每个图的所有起始节点并确定所有简单路径。结果又是一个列表。对于每个列表项,节点名称被提取并重新调整为宽格式的 data.table。列重命名为LC1LC2等。

在每一步中,我们都会得到一个由rbindlist() 组合的data.tables 列表。 fill 参数是必需的,因为列数可能会有所不同。对 rbindlist() 的最终调用使用idcol 参数来标记与Item 关联的行。

数据

样本数据集已经过修改,以包含来自 OP 的 cmets herehere 的案例。

library(data.table)
lctolc <- fread("
Item     LC     ToLC
8T4121  AB12    BC34
8T4121  MN12    AB12
8T4121  MW92    WK14
8T4121  WK14    RM11
8T4121  WK14    RS11
8T4121  RS11    OY01
AB7651  MW92    RS11
AB7651  RS11    OY01",
data.table = FALSE)

【讨论】:

  • 这里代码中没有涉及到一个极端情况。假设对于项目 8T4121,还有一个来自 LC“AB12”到LC“BC34”的关系,它与该项目的任何其他 LC 没有关系,那么这也应该出现在输出中,但现在它没有出现。
  • 另外,如果我们在第一行和第二行有 AB12 到 BC34 和第二行 MN12 到 AB12 的关系,那么这种关系应该是 MN12 到 AB12 到 BC34,但它是 AB12 到仅限 BC34。仅考虑关系的第一行而不考虑第二行
  • @AnshulSaravgi,确实,我错过了all_simple_paths()from 参数只接受一个节点。因此,我需要将调用包装在另一个 lapply() 循环中。请看固定代码版本。
  • 我遇到以下错误:rbindlist(., fill = TRUE, idcol = "Item") 中的错误:尝试在 SET_STRING_ELT 中设置索引 50611/50611 你能帮我解决这个问题吗?
  • @stackoverflow.com/users/3817004/uwe 知道如何为大型数据集解决它
猜你喜欢
  • 1970-01-01
  • 2021-03-02
  • 2019-06-08
  • 2015-01-16
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多