R中dplyr包中变异函数的奇怪行为

Posted

技术标签:

【中文标题】R中dplyr包中变异函数的奇怪行为【英文标题】:Weird behavior of mutate function from dplyr package in R 【发布时间】:2015-06-26 04:40:04 【问题描述】:

我正在制作一个有尺寸的集合

dim(data)
[1] 419612      2

第二列看起来或多或少像这样:

> unique(data[1:50,"topics"])
[1] "dom":2.0,"moda":3.0,"rodzina":1.55,"praca":1.42,"finanse":1.96,"edukacja":1.67,"sport":1.96,"muzyka":1.52,"kuchnia":1.8,"plotka":1.8,"zdrowie":1.12,"kibic":1.8,"uroda":2.32,"gra":2.94,"motoryzacja":1.33,"kultura":1.42,"film":3.14,"podróż":1.9,"technologia":1.31
[2] "rodzina":2.99,"kultura":4.46,"muzyka":4.5                                                                                                                                                                                                                            
[3] "dom":1.93,"rodzina":5.37,"zwierzęta":3.0,"praca":4.3,"finanse":2.11,"sport":2.1,"muzyka":2.99,"nieruchomość":2.8,"kuchnia":6.4,"plotka":2.1,"zdrowie":3.79,"gra":4.25,"motoryzacja":2.57,"kultura":3.13,"film":4.4,"podróż":3.21                                     
[4] "plotka":9.5,"uroda":10.06,"kultura":15.67,"muzyka":29.97                                                                                                                                                                                                             
[5] "dom":2.99,"rodzina":2.5,"edukacja":3.85,"sport":1.17,"muzyka":1.23,"nieruchomość":2.95,"kuchnia":1.42,"wnętrze":1.33,"kibic":1.17,"ogród":1.33,"motoryzacja":1.17,"film":1.17,"podróż":1.57                                                                          
[6] "kuchnia":4.38,"plotka":1.33,"rodzina":1.61,"film":1.33                                                                                                                                                                                                               
37530 Levels: "biznes":1.0 ... "zwierzęta":9.96,"podróż":9.97

对于每一行,我想从topics 列中选择: 符号后等级最高的单词。我尝试使用 dplyr 包中的 mutate 函数,它看起来不起作用。使用stringi 包制作的字符的操作是stringr 的更快版本。我的代码和此操作的结果如下。任何人都知道为什么我在此操作后的每一行都得到相同的值,以及如何在不使用for 循环的情况下达到预期的结果?

> data2 <- data %>%
+   mutate( xx = topics %>%
+             stri_extract_all_regex(pattern = "[a-zA-Z0-9óśćłźżęą\\.\\s]+") %>% 
+             unlist %>% 
+             data.frame( topic = .[seq(1,length(.), by=2)], 
+                         waga = .[seq(2,length(.), by=2)] )  %>% 
+             select( topic, waga) %>% arrange( desc( waga)) %>%
+             unique() %>%
+             .[1,1]
+             )
> table(data2$xx)[ which(table(data2$xx) > 1) ]
kuchnia 
 419612 

我添加了额外的列nr,这是一个行号,然后我愚蠢地在该列上添加了group_byed 和summarised 而不是mutate,并实现了我想要的......但是我不为我的代码感到自豪。还有其他想法吗?

daneBC1 <- data %>% 
  group_by( nr)  %>%
  summarise( bc1 = topics %>%
               stri_extract_all_regex(pattern = "[a-zA-Z0-9óśćłźżęą\\.\\s]+") %>% 
               unlist %>% 
               data.frame( topic = .[seq(1,length(.), by=2)], 
                           waga = .[seq(2,length(.), by=2)] )  %>% 
               select( topic, waga) %>% arrange( desc( waga)) %>%
               unique() %>%
               .[1,1] )



daneBC1$bc1 %>% table

        dom    edukacja        film     finanse         gra       kibic     kuchnia     kultura 
     119802       79487       55569       38134       30425       21757       16371       12356 
       moda motoryzacja      muzyka      plotka      podróż       praca     rodzina       sport 
      11103        7264        6357        4855        3520        3005        2317        2183 
technologia       uroda     zdrowie 
       1441        1055         740 

样本数据

library(archivist)
data <- loadFromGithubRepo( "97f74c5a10f510cce39eafb0d9a1a9e8", 
user="MarcinKosinski", repo="Museum", value = TRUE )

【问题讨论】:

为什么要使用正则表达式而不是将其读取为 JSON..?您是否也检查过问题是否不在于数据保存为因子而不是字符(为什么要在此处考虑因子?)? 顺便说一句,你能提供示例数据吗? @Tim 我已经用最后的示例数据更新了我的评论。 @Tim 现在我看到将rjson 包中的fromJSON 函数应用于每一行可能更具可读性,但正如您所见,简单的正则表达式也可以工作:) 但mutatefunction 不行.. 是的,但我仍然会坚持使用其中一个 JSON 库,因为 (a) 它们是为此类数据结构设计的,因此可能不太容易出错,(b) 可能比使用正则表达式更快。如果您的项目中存在性能问题,我会检查它。 【参考方案1】:

您的 mutate() 函数未“矢量化”。 Mutate 不是一次对一行进行操作,而是将整个列作为向量进行操作。您的 unlist.[1,1] 提取正在获取所有行的值并折叠为一个向量和一个值。

您可以使用

制作矢量化转换函数
extr <- Vectorize(. %>%
         stri_extract_all_regex(pattern = "[a-zA-Z0-9óśćłźżęą\\.\\s]+") %>% 
         unlist %>% 
         data.frame( topic = .[seq(1,length(.), by=2)], 
                     waga = .[seq(2,length(.), by=2)] )  %>% 
         select( topic, waga) %>% arrange( desc( waga)) %>%
         unique() %>%
         .[1,1])

然后使用它

data %>% mutate( xx = extr(topics))

虽然我同意其他人的观点,因为您有 JSON 数据,最好使用 JSON 解析器正确解析这些数据,而不是尝试使用正则表达式重新发明***。

【讨论】:

以上是关于R中dplyr包中变异函数的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

带有 dplyr 的用户定义函数 - 变异列是一个参数

尝试安装dplyr时R的意外行为

R dplyr 在列索引上发生变异

R语言广义线性模型函数GLMR中有几种logistic回归扩展和变异robust包中的glmRob函数鲁棒logistic回归ms包中的lrm函数拟合序数逻辑回归

R - 如何使用准引号动态构造变异函数名称

自定义函数与dplyr变异或汇总因子中的不同级别?