提醒我如何循环几行(如申请等)

问题描述 投票:0回答:3

我有一个for循环使用grepl来匹配数据框的一个字的首字母缩写词和一个字典键,并创建一个列,其中包含要绑定到原始数​​据帧的键的字典值。

我有一个for循环工作,代码可以工作/给我我需要的东西。

#Example dataframe to loop over 
loop <- data.frame(
  acronym = c("cmr", "cmr", "den", "den", "nmw", "nmw"),
  profession = c("chinese medical practitioner", "chinese medical practitioner",
                 "dentist", "dentist", "medical practitioner", "nurse"),
  stringsAsFactors = FALSE
)
#The dictionary I created to provide values to each key
dic <- list(
  cmr = "chinese medical practitioner",
  den = "dentist",
  med = "medical practitioner",
  nmw = "nurse"
)

带有列表的for循环,用于存储每次迭代的字典值,其中数据框中的acronym与字典中的键之间存在匹配。然后,我将未列出的值列表绑定到数据帧loop。这个例子'纠正'循环中的profession列,所以利用字典和acronym列清理数据。

column <- list()
for (i in 1:length(loop$acronym)){
  for (j in 1:length(dic)){
    if (grepl(names(dic)[j], loop$acronym[i], loop$code)){
      column[i] <- dic[j]
    }
  }
}
cbind(unlist(column),loop)

但是,我想使用apply或来自tidyverse世界的东西解决问题。我真的不想从data.table获得解决方案,除非它令人惊讶,然后我可能会开始考虑学习data.table。

r loops apply
3个回答
3
投票

使用base R的一种方法是使用stack然后使用merge

merge(loop, stack(dic), by.x = "acronym", by.y = "ind")

#  acronym                   profession                       values
#1     cmr chinese medical practitioner chinese medical practitioner
#2     cmr chinese medical practitioner chinese medical practitioner
#3     den                      dentist                      dentist
#4     den                      dentist                      dentist
#5     nmw         medical practitioner                        nurse
#6     nmw                        nurse                        nurse

stack(dic)将命名列表转换为数据帧

stack(dic)
#                        values ind
#1 chinese medical practitioner cmr
#2                      dentist den
#3         medical practitioner med
#4                        nurse nmw

2
投票

如果我们在代码中用list()替换c(),使dic成为命名向量而不是列表,那么我们可以使用向量名称作为索引在一行中完成此操作:

dic <- c(
  cmr = "chinese medical practitioner",
  den = "dentist",
  med = "medical practitioner",
  nmw = "nurse"
)

loop$code = dic[loop$acronym]
loop
#   acronym                   profession                         code
# 1     cmr chinese medical practitioner chinese medical practitioner
# 2     cmr chinese medical practitioner chinese medical practitioner
# 3     den                      dentist                      dentist
# 4     den                      dentist                      dentist
# 5     nmw         medical practitioner                        nurse
# 6     nmw                        nurse                        nurse

2
投票

当我将相同或类似类型的对象放在一起时,我经常会更好地运行这些任务 - 列表包含列表,数据框包含数据框等。

有几种快速的方法可以将字典放入数据框中,这样可以更容易地与loop数据连接。第一个只是获取列表的名称和列表的展平版本,并创建两者的列。

library(dplyr)
library(purrr)

dict_df <- tibble(
  acronym = names(dic), 
  profession = flatten_chr(dic)
)
dict_df
#> # A tibble: 4 x 2
#>   acronym profession                  
#>   <chr>   <chr>                       
#> 1 cmr     chinese medical practitioner
#> 2 den     dentist                     
#> 3 med     medical practitioner        
#> 4 nmw     nurse

您也可以使用较新的函数tibble::enframe,它可以从单个向量创建数据帧(就像您在unlist之后得到的那样)并使用向量的名称作为列。这里的优点是它可能适合更大的管道工作流程 - 获得与上面相同的输出。

unlist(dic) %>% 
  tibble::enframe(name = "acronym", value = "profession")

然后将原始数据与字典连接起来。 dplyr*_join函数可选择使用后缀,这些后缀将附加到不是连接列但具有相同名称的列。在这里,您可以看到哪个专业列来自原始数据,哪些来自更正。

loop %>%
  left_join(dict_df, by = "acronym", 
            suffix = c("_loop", "_dict"))
#>   acronym              profession_loop              profession_dict
#> 1     cmr chinese medical practitioner chinese medical practitioner
#> 2     cmr chinese medical practitioner chinese medical practitioner
#> 3     den                      dentist                      dentist
#> 4     den                      dentist                      dentist
#> 5     nmw         medical practitioner                        nurse
#> 6     nmw                        nurse                        nurse

reprex package创建于2019-04-19(v0.2.1)

© www.soinside.com 2019 - 2024. All rights reserved.