我有一个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或dydyverse世界中的一些东西来解决问题。我真的不想要data.table的解决方案,除非它令人惊讶,否则我可能会开始考虑学习data.table。
答案 0 :(得分:3)
使用基数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
答案 1 :(得分: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 :(得分: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
的{{1}}函数可以选择带后缀,这些后缀将附加到不是联接列但名称相同的列中。在这里,您可以查看哪个专业栏来自原始数据,哪个专业栏来自更正。
*_join
由reprex package(v0.2.1)于2019-04-19创建