有条件地编辑值标签的有效方法
Efficient way to conditionally edit value labels
我正在处理包含值标签的调查数据。避风港包允许导入带有值标签属性的数据。有时这些值标签需要以常规方式进行编辑。
我在此处给出的示例非常简单,但我正在寻找可应用于大型 data.frames.
中类似问题的解决方案
d <- dput(structure(list(var1 = structure(c(1, 2, NA, NA, 3, NA, 1, 1), labels = structure(c(1,
2, 3, 8, 9), .Names = c("Protection of environment should be given priority",
"Economic growth should be given priority", "[DON'T READ] Both equally",
"[DON'T READ] Don't Know", "[DON'T READ] Refused")), class = "labelled")), .Names = "var1", row.names = c(NA,
-8L), class = c("tbl_df", "tbl", "data.frame")))
d$var1
<Labelled double>
[1] 1 2 NA NA 3 NA 1 1
Labels:
value label
1 Protection of environment should be given priority
2 Economic growth should be given priority
3 [DON'T READ] Both equally
8 [DON'T READ] Don't Know
9 [DON'T READ] Refused
如果值标签以“[请勿阅读]”开头,我想从标签的开头删除“[请勿阅读]”并在结尾添加“(VOL)”。所以,“[不要阅读] 两者都一样”现在应该是 "Both equally (VOL)."
当然,使用 haven 的相关标签包中的函数编辑这个单独的变量是很简单的。但我想将此解决方案应用于 data.frame.
中的所有变量
library(labelled)
val_labels(d$var1) <- c("Protection of environment should be given priority" = 1,
"Economic growth should be given priority" = 2,
"Both equally (VOL)" = 3,
"Don't Know (VOL)" = 8,
"Refused (VOL)" = 9)
如何以一种可以应用于 data.frame 中的每个变量的方式直接实现上面函数的结果?
解决方案必须不管 具体值如何。 (在这种情况下,需要更改的是值 3,8 和 9,但不一定是这种情况)。
有几种方法可以做到这一点。您可以使用 lapply()
或(如果您想要一个(ish)-liner),您可以使用 mutate()
:
的任何范围变体
1).使用 lapply()
此方法遍历所有带有 gsub()
的列以删除不需要的部分并将 " (VOL)"
添加到字符串的末尾。当然,您也可以将其与子集一起使用!
d[] <- lapply(d, function(x) {
labels <- attributes(x)$labels
names(labels) <- gsub("\[DON'T READ\]\s*(.*)", "\1 (VOL)", names(labels))
attributes(x)$labels <- labels
x
})
d$var1
[1] 1 2 NA NA 3 NA 1 1
attr(,"labels")
Protection of environment should be given priority Economic growth should be given priority
1 2
Both equally (VOL) Don't Know (VOL)
3 8
Refused (VOL)
9
attr(,"class")
[1] "labelled"
2) 使用 mutate_all()
使用相同的逻辑(结果相同),您可以更简洁地更改标签的名称:
d %>%
mutate_all(~{names(attributes(.)$labels) <- gsub("\[DON'T READ\]\s*(.*)", "\1 (VOL)", names(attributes(.)$labels));.}) %>%
map(attributes) # just to check on the result
我正在处理包含值标签的调查数据。避风港包允许导入带有值标签属性的数据。有时这些值标签需要以常规方式进行编辑。
我在此处给出的示例非常简单,但我正在寻找可应用于大型 data.frames.
中类似问题的解决方案d <- dput(structure(list(var1 = structure(c(1, 2, NA, NA, 3, NA, 1, 1), labels = structure(c(1,
2, 3, 8, 9), .Names = c("Protection of environment should be given priority",
"Economic growth should be given priority", "[DON'T READ] Both equally",
"[DON'T READ] Don't Know", "[DON'T READ] Refused")), class = "labelled")), .Names = "var1", row.names = c(NA,
-8L), class = c("tbl_df", "tbl", "data.frame")))
d$var1
<Labelled double>
[1] 1 2 NA NA 3 NA 1 1
Labels:
value label
1 Protection of environment should be given priority
2 Economic growth should be given priority
3 [DON'T READ] Both equally
8 [DON'T READ] Don't Know
9 [DON'T READ] Refused
如果值标签以“[请勿阅读]”开头,我想从标签的开头删除“[请勿阅读]”并在结尾添加“(VOL)”。所以,“[不要阅读] 两者都一样”现在应该是 "Both equally (VOL)."
当然,使用 haven 的相关标签包中的函数编辑这个单独的变量是很简单的。但我想将此解决方案应用于 data.frame.
中的所有变量library(labelled)
val_labels(d$var1) <- c("Protection of environment should be given priority" = 1,
"Economic growth should be given priority" = 2,
"Both equally (VOL)" = 3,
"Don't Know (VOL)" = 8,
"Refused (VOL)" = 9)
如何以一种可以应用于 data.frame 中的每个变量的方式直接实现上面函数的结果?
解决方案必须不管 具体值如何。 (在这种情况下,需要更改的是值 3,8 和 9,但不一定是这种情况)。
有几种方法可以做到这一点。您可以使用 lapply()
或(如果您想要一个(ish)-liner),您可以使用 mutate()
:
1).使用 lapply()
此方法遍历所有带有 gsub()
的列以删除不需要的部分并将 " (VOL)"
添加到字符串的末尾。当然,您也可以将其与子集一起使用!
d[] <- lapply(d, function(x) {
labels <- attributes(x)$labels
names(labels) <- gsub("\[DON'T READ\]\s*(.*)", "\1 (VOL)", names(labels))
attributes(x)$labels <- labels
x
})
d$var1
[1] 1 2 NA NA 3 NA 1 1
attr(,"labels")
Protection of environment should be given priority Economic growth should be given priority
1 2
Both equally (VOL) Don't Know (VOL)
3 8
Refused (VOL)
9
attr(,"class")
[1] "labelled"
2) 使用 mutate_all()
使用相同的逻辑(结果相同),您可以更简洁地更改标签的名称:
d %>%
mutate_all(~{names(attributes(.)$labels) <- gsub("\[DON'T READ\]\s*(.*)", "\1 (VOL)", names(attributes(.)$labels));.}) %>%
map(attributes) # just to check on the result