我有一个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。
使用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
如果我们在代码中用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
当我将相同或类似类型的对象放在一起时,我经常会更好地运行这些任务 - 列表包含列表,数据框包含数据框等。
有几种快速的方法可以将字典放入数据框中,这样可以更容易地与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)