2

应用标签是使调查数据在报告时易于理解的重要部分

所以我能找到的最好的例子使用 expss::apply_labels() 例如著名的 mtcars 例子https://cran.r-project.org/web/packages/expss/vignettes/tables-with-labels.html

作为输入,这需要一个 data.table 和一个逗号分隔的赋值对列表,例如

apply_labels(dt, col1 = "label1", col2 = "label2", col3 = "label3")

如果您有一个数据文件和几列,这很好,并且每次都输入它们可能会很麻烦,但如果您有很多数据文件,它就不是很有帮助。那么如何加载格式的 csv 元数据文件:

Col1 Col2 Col3

标签1 标签2 标签3

其中 Col 名称与数据表中的相同名称匹配

这意味着有效地翻译元数据 csv 文件,以便生成

col n = "标签n "

对于每一列。

到目前为止,我发现最大的问题是应用标签列名是对象而不是字符串,并且很难将字符串转换为正确范围内的对象。

这是我必须去的地方

    library(expss)
    library(data.table)
    library(glue)

    readcsvdata <- function(dfile)
     {
        rdata <- fread(file = dfile, sep = "," , quote = "\"" , header = TRUE, 
        stringsAsFactors = FALSE, na.strings = getOption("datatable.na.strings","NA"))
        return(rdata)
        }

    rawdatafilename <- "testdata.csv"
    rawmetadata <- "metadata.csv"

    mdt <- readcsvdata(rawmetadata)
    rdt <-readcsvdata(rawdatafilename)
    commonnames <- intersect(names(mdt),names(rdt))  # find common 
    qlabels <- as.character(mdt[1, commonnames, with = FALSE])

    comslist <- list()
    for (i in 1:length(commonnames)) # loop through commonnames and qlabels
          {  
          if (i == length(commonnames))
              {x <- glue('{commonnames[i]} = "{qlabels[i]}"')} # no comma for final item
              else 
              {x <- glue('{commonnames[i]} = "{qlabels[i]}",')} # comma for next item

          comslist[[i]] <- x
    }

comstring <- paste(unlist(comslist), collapse = '')

tdt = apply_labels(tdt, eval(parse(text = comstring)))

产生

解析错误(文本 = comstring)::1:24:意外','1:varone =“Label1”,^

哦, print(comstring) 产生:

[1] "varone = \"问题一\",vartwo = \"问题二\",varthree = \"问题三\",varfour = \"问题四\",varfive = \"问题五\",varsix = \"问题六\",varseven = \"问题七\",vareight = \"问题八\",varnine = \"问题九\",varten = \"问题十\""

4

2 回答 2

1

我没有expss方便,但我认为这通常是关于如何在 R 中以编程方式分配函数参数。

如果您从包含您需要的三个配对的 CSV 文件开始,

csvdat <- read.csv(stringsAsFactors=FALSE, text="
col1,col2,col3
label1,label2,label3")

我将编写一个伪函数(因为我没有expss,而且它并不重要),它动态地接受第一个参数和零个或多个后续参数。

my_fake_labels <- function(x, ...) {
  dots <- list(...)
  message("x labels   : ", paste(sQuote(colnames(x)), collapse = ", "))
  message("other names: ", paste(sQuote(names(dots)), collapse = ", "))
}
origDT <- data.table(aa=1, bb=2)

my_fake_labels(origDT, col1="label1", col2="label2", col3="label3")
# x labels   : 'aa', 'bb'
# other names: 'col1', 'col2', 'col3'

这是您要避免的手动参数设置。(我知道我在这里没有做任何标签设置,让我们暂时忽略它。)

执行此操作的编程方式,origDT用作第一个参数,并将元素csvdat用作第二个和后续参数:

do.call(my_fake_labels, c(list(origDT), csvdat))
# x labels   : 'aa', 'bb'
# other names: 'col1', 'col2', 'col3'

to 的第二个参数do.call需要是 a list,可以选择命名。由于 a data.frame(因此 a data.table)只是一个美化的 named list,所以这符合要求。这样做是获取列表的每个元素并将其应用为函数的相应参数(的第一个参数do.call)。

list(origDT)是因为通常该c(...)函数会连接两个列表的列/元素。如果我们只是这样做c(origDT, csvdat),那么函数将使用ncol(origDT) + ncol(csvdat)参数调用,而不是期望的1 + ncol(csvdat)。为此,请c(list(origDT), ...)确保整体origDT是函数的第一个参数。

(以编程方式形成而不需要外部文件也可能很容易csvdat,但我猜你有理由通过 CSV 来完成。)

于 2020-05-27T04:12:49.970 回答
1

apply_labels对于来自外部字典的分配标签不是很方便。您可以var_lab改用:

library(expss)
library(data.table)

readcsvdata <- function(dfile)
{
    rdata <- fread(file = dfile, sep = "," , quote = "\"" , header = TRUE, 
                   stringsAsFactors = FALSE, na.strings = getOption("datatable.na.strings","NA"))
    return(rdata)
}

rawdatafilename <- "testdata.csv"
rawmetadata <- "metadata.csv"

mdt <- readcsvdata(rawmetadata)
rdt <-readcsvdata(rawdatafilename)
commonnames <- intersect(names(mdt),names(rdt))  # find common 
qlabels <- as.list(mdt[1, commonnames, with = FALSE])


for (each_name in commonnames) # loop through commonnames and qlabels
{  
    var_lab(rdt[[each_name]]) <- qlabels[[each_name]]
}

值标签也有类似的val_lab功能。apply_dictionary此外,您可能对create_dictionary功能感兴趣。要获得有关他们的帮助?apply_dictionary,请在控制台中输入。

于 2020-05-29T22:33:10.597 回答