首页 > 解决方案 > 关于 dplyr 和 mutate 中的 map_chr() 函数的清晰性?

问题描述

对不起,函数式编程“循环”让我有点抓耳挠腮purrr

我知道要使用自己的非向量化函数map_chr(),我可以使用它mutate来生成 2 个新列。但是在某一时刻,我不明白 map_chr 是否每次都占用整个列并每次都生成列表输出,或者只取一个值并将该一个计算输出值放在新变量中。基本上 - 如果对于SHASUM列中的每个变量 map_chr 只返回一个值,或者自动从中选择正确值的值列表?很抱歉这个问题太模糊了,但我发现很难理解,不知道里面发生了pipes什么mutate

我的示例代码如下。

这是对 map_chr() 的有效/正确使用(以及更一般地来自 purrr 的映射函数)还是我应该做的更好的事情?

library(tidyverse)
library(lubridate)
library(urlshorteneR)

longLinkBase <- "https://lime.survey.server/334443?newtest=Y?&QID="

initData <- structure(list(SHASUM = c("4db194d", "44fc459", "eb81eb4", "3c37606", "1165fc2", "fd4f56b"), StartDate = c(44172L, 44172L, 44172L, 44172L, 44172L, 44172L)), row.names = c(NA, 6L), class = "data.frame")
# convert Excel date serial number into proper date 
initData$StartDate <- as.Date(initData$StartDate, origin = "1899-12-30")

getlongLink <- function(x,y){
  # combine long link base with the (subject) code 
  z <- URLencode(paste0(y,x))
  return(z)
}

getShortLink <- function(x){
  Sys.sleep(2)
  z <- isgd_LinksShorten(x)
  return(z)
}

# 3 Lines below are my question, really:
initData <- initData %>% 
  mutate(longLink = map_chr(SHASUM,getlongLink,y=longLinkBase))  %>% 
  mutate(shortLink = map_chr(longLink,getShortLink))

### Write out data as CSV file
write.csv(initData,file=paste0("./output/","shortLinks_",format(Sys.time(),"%Y-%m-%d_%H-%M_%b"),".csv"),na="")

标签: rdplyrpurrr

解决方案


map_chr是一个隐藏的循环。使用它的好处是代码可以通过管道/链接在一起,并且可读性更好。

map_chr(SHASUM,getlongLink,y=longLinkBase)和做一样 -

getlongLink(initData$SHASUM[1], longLinkBase)
getlongLink(initData$SHASUM[2], longLinkBase)
getlongLink(initData$SHASUM[3], longLinkBase)
.....
.....

不同之处在于您不会“看到”这些单独的调用,它们是在map_chr. 此调用中的每一个都返回一个值,该值存储为一个新列。

我认为您的代码总体上是好的,我只能建议一个小的改进,您可以将两个mutate调用组合成一个调用。

initData <- initData %>% 
  mutate(longLink = map_chr(SHASUM,getlongLink,y=longLinkBase),
         shortLink = map_chr(longLink,getShortLink))

推荐阅读