运行 跨列的函数,不剥离标签属性
Run a function across columns without stripping Labelled attributes
我有大量 SPSS 文件,我需要生成看起来像文件中数据的随机数据。
当我读入 SPSS 文件时(使用 haven
的 read_sav
),它们带有变量和值标签(来自 labelled),我希望每个变量都有那些加扰数据后写入 SPSS 文件时具有相同的属性。但是,当我独立地打乱每一列的序列时,sapply
会剥离 Labeled 属性(因为它返回一个矩阵,我将其强制转换为 data.frame
)。
如何在不剥离这些属性的情况下执行此操作?请参见下面的示例:
dat<-data.frame(a=c(1,2,3,4,5,6,7,8,9,10),b=c("a","b","c","d","e","f","g","h","i","j"))
var_label(dat$a)<-"The first variable"
val_labels(dat$a)<-c(first=1,
second=2,
third=3,
fourth=4,
fifth=5,
sixth=6,
seventh=7,
eighth=8,
ninth=9,
tenth=10)
var_label(dat$b)<-"The second variable"
# Variable has variable and value labels
dat$a
faker<-function(thing){
thing<-sample(thing,length(thing),replace=TRUE)
thing
}
rat<-as.data.frame(sapply(dat,faker))
# Variable no longer has variable and value labels
rat$a
编辑以更正代码最后一行的拼写错误,该行是 dat$a,应该是 rat$a
(首先,我假设您重新分配给 rat
应该确实是 dat
,否则它不可重现并且 不应该是 因为 dat
在形成 rat
时没有改变。)
你使用的sapply
是均质化和dumbing-down数据,切换到lapply
。
# ...
dat<-as.data.frame(sapply(dat,faker))
dat$a
# [1] "1" "7" "5" "7" "10" "2" "1" "4" "9" "4"
修复,
dat <- as.data.frame(lapply(dat,faker))
dat$a
# <labelled<double>[10]>: The first variable
# [1] 2 3 8 9 8 5 5 10 1 3
# Labels:
# value label
# 1 first
# 2 second
# 3 third
# 4 fourth
# 5 fifth
# 6 sixth
# 7 seventh
# 8 eighth
# 9 ninth
# 10 tenth
旁注:在将某项应用于框架的所有列时,我倾向于使用 dat[] <- lapply(...)
而不是 dat <- as.data.frame(lapply(...))
,因为它保留了框架的属性和 replaces/augments 列' 内容。
# ...
dat[] <- lapply(dat, faker)
dat$a
# <labelled<double>[10]>: The first variable
# [1] 4 8 7 7 9 7 9 1 3 5
# Labels:
# value label
# 1 first
# 2 second
# 3 third
# 4 fourth
# 5 fifth
# 6 sixth
# 7 seventh
# 8 eighth
# 9 ninth
# 10 tenth
我有大量 SPSS 文件,我需要生成看起来像文件中数据的随机数据。
当我读入 SPSS 文件时(使用 haven
的 read_sav
),它们带有变量和值标签(来自 labelled),我希望每个变量都有那些加扰数据后写入 SPSS 文件时具有相同的属性。但是,当我独立地打乱每一列的序列时,sapply
会剥离 Labeled 属性(因为它返回一个矩阵,我将其强制转换为 data.frame
)。
如何在不剥离这些属性的情况下执行此操作?请参见下面的示例:
dat<-data.frame(a=c(1,2,3,4,5,6,7,8,9,10),b=c("a","b","c","d","e","f","g","h","i","j"))
var_label(dat$a)<-"The first variable"
val_labels(dat$a)<-c(first=1,
second=2,
third=3,
fourth=4,
fifth=5,
sixth=6,
seventh=7,
eighth=8,
ninth=9,
tenth=10)
var_label(dat$b)<-"The second variable"
# Variable has variable and value labels
dat$a
faker<-function(thing){
thing<-sample(thing,length(thing),replace=TRUE)
thing
}
rat<-as.data.frame(sapply(dat,faker))
# Variable no longer has variable and value labels
rat$a
编辑以更正代码最后一行的拼写错误,该行是 dat$a,应该是 rat$a
(首先,我假设您重新分配给 rat
应该确实是 dat
,否则它不可重现并且 不应该是 因为 dat
在形成 rat
时没有改变。)
你使用的sapply
是均质化和dumbing-down数据,切换到lapply
。
# ...
dat<-as.data.frame(sapply(dat,faker))
dat$a
# [1] "1" "7" "5" "7" "10" "2" "1" "4" "9" "4"
修复,
dat <- as.data.frame(lapply(dat,faker))
dat$a
# <labelled<double>[10]>: The first variable
# [1] 2 3 8 9 8 5 5 10 1 3
# Labels:
# value label
# 1 first
# 2 second
# 3 third
# 4 fourth
# 5 fifth
# 6 sixth
# 7 seventh
# 8 eighth
# 9 ninth
# 10 tenth
旁注:在将某项应用于框架的所有列时,我倾向于使用 dat[] <- lapply(...)
而不是 dat <- as.data.frame(lapply(...))
,因为它保留了框架的属性和 replaces/augments 列' 内容。
# ...
dat[] <- lapply(dat, faker)
dat$a
# <labelled<double>[10]>: The first variable
# [1] 4 8 7 7 9 7 9 1 3 5
# Labels:
# value label
# 1 first
# 2 second
# 3 third
# 4 fourth
# 5 fifth
# 6 sixth
# 7 seventh
# 8 eighth
# 9 ninth
# 10 tenth