Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用dplyr和/或tidyr组合/排序列_R_Dplyr_Igraph_Tidyr - Fatal编程技术网

使用dplyr和/或tidyr组合/排序列

使用dplyr和/或tidyr组合/排序列,r,dplyr,igraph,tidyr,R,Dplyr,Igraph,Tidyr,编辑:我尝试了下面的解决方案,但由于我需要将因子转换为字符并返回到因子,我丢失了一些重要信息 有了这张桌子,我想把它从这里分类 From To count A B 2 A C 1 C A 3 B C 1 对此, From To count 1 A B 2 2 A C 4 3 B C 1 到目前为止,我看到两种选择,一种是: df[1:2] <- t

编辑:我尝试了下面的解决方案,但由于我需要将因子转换为字符并返回到因子,我丢失了一些重要信息

有了这张桌子,我想把它从这里分类

From    To  count
A       B     2
A       C     1
C       A     3
B       C     1
对此,

  From To count
1    A  B     2
2    A  C     4
3    B  C     1
到目前为止,我看到两种选择,一种是:

df[1:2] <- t(apply(df[1:2], 1, sort))    
aggregate(count ~ From + To, df, sum)
这是相当缓慢的,因为我正在处理9.000.000个观察值。或者简单地将其转换为iGraph网络,并合并边

g <- graph_from_data_frame(df, directed = TRUE, vertices = nodes)
g <- as.undirected(g, mode = "mutual", edge.attr.comb=list(weight = "sum"))
我遇到的两个问题是,我提到的第一个选项实际上应该使用dplyr或tidyr,但到目前为止我还不知道如何使用它

network/igraph选项比tapply选项快,但我仍然需要将该图转换回data.table以进行进一步分析

有没有关于如何使用dplyr或tidyr运行tapply选项的想法

我们可以使用pmin/pmax。应该快一点

library(dplyr)
df1 %>% 
    group_by(From1 = pmin(From, To), To = pmax(From, To)) %>% 
    summarise(count = sum(count)) %>%
    rename(From = From1)
#  From    To count
#  <chr> <chr> <int>
#1     A     B     2
#2     A     C     4
#3     B     C     1
我们可以使用pmin/pmax。应该快一点

library(dplyr)
df1 %>% 
    group_by(From1 = pmin(From, To), To = pmax(From, To)) %>% 
    summarise(count = sum(count)) %>%
    rename(From = From1)
#  From    To count
#  <chr> <chr> <int>
#1     A     B     2
#2     A     C     4
#3     B     C     1

在base R中,我们可以使用非公式界面将akrun的pmin和pmax建议与聚合结合起来,如下所示:

aggregate(df$count, list(From=pmin(df$From, df$To), To=pmax(df$From, df$To)), sum)
  From To x
1    A  B 2
2    A  C 4
3    B  C 1
注意,这要求df$From和df$To是字符向量,而不是因子

时间安排 此方法比使用apply更快,因为它不涉及到矩阵的转换。使用下面较大的数据集,通过900万次观察,在我的计算机上使用pmin和pmax和aggregate完成的时间为14.5秒,而OP使用apply的方法需要442.2秒或30倍

资料

大样本数据


在base R中,我们可以使用非公式界面将akrun的pmin和pmax建议与聚合结合起来,如下所示:

aggregate(df$count, list(From=pmin(df$From, df$To), To=pmax(df$From, df$To)), sum)
  From To x
1    A  B 2
2    A  C 4
3    B  C 1
注意,这要求df$From和df$To是字符向量,而不是因子

时间安排 此方法比使用apply更快,因为它不涉及到矩阵的转换。使用下面较大的数据集,通过900万次观察,在我的计算机上使用pmin和pmax和aggregate完成的时间为14.5秒,而OP使用apply的方法需要442.2秒或30倍

资料

大样本数据


不幸的是,我得到了以下错误:错误:向无效对象添加类因子。@FilipeTeixeira我认为From/to列是字符类。因此,您可以对每个字符进行df1%>%的变异,从:到%>%group\U by…非常有效。谢谢。不幸的是,我发现这个方法还有另一个问题。将变量变为字符,再变回因子,意味着我失去了初始级别。我可以创建一个查找表,但这里的想法实际上是有一个更简单、更快的代码。@FilipeTeixeira获得初始级别将很困难,因为我们正在更改值。例如,在您的eexample中,第一列的级别为“A”、“C”、“B”,但在输出中,“C”不存在,类似地,在“ToUnfortute”中,我遇到以下错误:错误:将类因子添加到无效对象。@Filipetixeira我认为From/to列是字符类。因此,您可以对每个字符进行df1%>%的变异,从:到%>%group\U by…非常有效。谢谢。不幸的是,我发现这个方法还有另一个问题。将变量变为字符,再变回因子,意味着我失去了初始级别。我可以创建一个查找表,但这里的想法实际上是有一个更简单、更快的代码。@FilipeTeixeira获得初始级别将很困难,因为我们正在更改值。例如,在您的eexample中,第一列的级别为'A'、'C'、'B',但在输出中,'C'不在那里,类似地,在'To@Imo非常感谢。我与基地的问题是,它是我的9.000.000观察缓慢的事实。下面的解决方案以应有的速度运行。请查看我的更新,其中包括时间安排。通常情况下,是某个特定的实现速度慢,而不是以R为基础。@Imo,但它同样会导致因素问题,我稍后需要这些因素进行数据验证。@Imo谢谢。我与基地的问题是,它是我的9.000.000观察缓慢的事实。下面的解决方案以应有的速度运行。请查看我的更新,其中包括时间安排。通常情况下,是某个特定的实现速度慢,而不是基于R本身,但它会再次导致因素问题,稍后我将需要这些因素进行数据验证。
library(tidyverse)
cols_before_merge <- c("From", "To")
out_cols <- c("col_1", "col_2")

df <- tibble::tribble(
  ~From, ~To, ~count,
  "A", "B", 2,
  "A", "C", 1,
  "C", "A", 3,
  "B", "C", 1,
)
df_out <- df %>%
  dplyr::mutate(
    key = purrr::pmap_chr(
      list(From, To),
      ~ stringr::str_c(stringr::str_sort(c(...)), collapse = "_")
    )
  )
merge_sort <- function(cols_values) {
  purrr::pmap_chr(
    cols_values,
    ~ stringr::str_c(stringr::str_sort(c(...)), collapse = "_")
  )
}

add_key <- function(cols) {
  # column names need to be evaluated using the dataframe as an environment
  cols_quosure <- rlang::enquo(cols)

  # column names should be symbols not strings
  cols_syms <- rlang::syms(cols)

  cols_values <- purrr::map(
    cols_syms,
    ~ rlang::eval_tidy(.x, rlang::quo_get_env(cols_quosure))
  )

  merge_sort(cols_values)
}



# Adding columns for key construction programmatically
df_out <- df %>%
  dplyr::mutate(key = add_key(cols_before_merge))
df_out %>%
  dplyr::count(key, name = "count") %>%
  tidyr::separate(key, sep = "_", into = out_cols) %>%
  dplyr::mutate_at(out_cols, as.factor)