【问题标题】:Function is returning all values instead of one when mapped映射时函数返回所有值而不是一个
【发布时间】:2021-05-10 01:21:51
【问题描述】:

希望获得一些关于如何映射一个函数的建议,该函数返回一个句子的可读性分数向量(最终将它们全部绑定)。我尝试了两种不同的方法,但到目前为止,我只知道如何使用for 循环来获取它。

library(quanteda.textstats)
haiku_df <- data.frame(id = c(1,2,3), 
                       sentences = c("Mapping a function",
                                     "Can sometimes leave me with more",
                                     "Questions than answers"))

我认为这会为每个列表返回一个分数向量,但它会重复它nrow(haiku_df) 次:

scores <- function(text,id){
  flesch_score <- textstat_readability(text, measure = "Flesch")$Flesch
  fog_score <- textstat_readability(text, measure = "FOG")$FOG
  row <- data.frame(id, flesch_score, fog_score)
  row
}
score_df <- list()
score_df <- lapply(haiku_df$sentences, scores, haiku_df$id)
score_df


> score_df
[[1]]
  id flesch_score fog_score
1  1        62.79       1.2
2  2        62.79       1.2
3  3        62.79       1.2

[[2]]
  id flesch_score fog_score
1  1      102.045       2.4
2  2      102.045       2.4
3  3      102.045       2.4

[[3]]
  id flesch_score fog_score
1  1        62.79       1.2
2  2        62.79       1.2
3  3        62.79       1.2

这是正确的方向,但仍然不正确(添加 n 作为参数):

scores2 <- function(text,id,n){
  flesch_score <- textstat_readability(text[n], measure = "Flesch")$Flesch
  fog_score <- textstat_readability(text[n], measure = "FOG")$FOG
  row <- data.frame(id[n], flesch_score, fog_score)
  row
}
score2_df <- list()
score2_df <- lapply(haiku_df$sentences, scores2, haiku_df$id, n = 1:nrow(haiku_df))


> score2_df
[[1]]
  id.n. flesch_score fleschkincaid_score
1     1        62.79            5.246667
2     2           NA                  NA
3     3           NA                  NA

[[2]]
  id.n. flesch_score fleschkincaid_score
1     1      102.045           0.5166667
2     2           NA                  NA
3     3           NA                  NA

[[3]]
  id.n. flesch_score fleschkincaid_score
1     1        62.79            5.246667
2     2           NA                  NA
3     3           NA                  NA

值得信赖的for 循环让我得到我想要的,但在扩大规模时显然会变慢。

score3_df <- list()
for (i in 1:nrow(haiku_df)){
  score3_df[[i]] <- scores(haiku_df$sentences[i],haiku_df$id[i])
}

> dplyr::bind_rows(score3_df)
  id flesch_score fog_score
1  1       62.790       1.2
2  2      102.045       2.4
3  3       62.790       1.2

感觉好像我忽略了一些非常简单的事情,但似乎无法弄清楚。 谢谢!

【问题讨论】:

    标签: r function lapply


    【解决方案1】:

    我们需要Map 而不是lapply,因为函数输入是对应“id”的“句子”的每个元素

    do.call(rbind, Map(scores, haiku_df$sentences, haiku_df$id))
    #.                                 id flesch_score fog_score
    #Mapping a function                1       62.790       1.2
    #Can sometimes leave me with more  2      102.045       2.4
    #Questions than answers            3       62.790       1.2
    

    也可以写成

    do.call(rbind, do.call(Map, c(f = scores, unname(haiku_df[2:1]))))
    

    或使用tidyverse

    library(dplyr)
    library(purrr)
    library(tidyr)
    haiku_df %>%
          transmute(out = map2(sentences, id, scores)) %>%
          unnest(out)
    

    -输出

    # A tibble: 3 x 3
    #     id flesch_score fog_score
    #  <dbl>        <dbl>     <dbl>
    #1     1         62.8       1.2
    #2     2        102.        2.4
    #3     3         62.8       1.2
    

    或使用rowwise

    haiku_df %>% 
        rowwise %>%
        transmute( scores(sentences, id)) %>%
        ungroup
    # A tibble: 3 x 3
    #     id flesch_score fog_score
    #  <dbl>        <dbl>     <dbl>
    #1     1         62.8       1.2
    #2     2        102.        2.4
    #3     3         62.8       1.2
    

    【讨论】:

    • 从来不知道Map。只是为了表明基础仍然可以有多么强大。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    相关资源
    最近更新 更多