在将数据对象转换为dataframe时,如何编写自定义函数以半自动化列命名
我正在尝试编写一个函数,它将接受一个列表对象(以特定格式)并返回一个数据帧。 这样做时,我有两个标准有些冲突:在将数据对象转换为dataframe时,如何编写自定义函数以半自动化列命名,r,function,tidyr,R,Function,Tidyr,我正在尝试编写一个函数,它将接受一个列表对象(以特定格式)并返回一个数据帧。 这样做时,我有两个标准有些冲突: 返回的数据帧应具有指示每列内容的列名(即,不是列a,列b,等等) 函数应该接受一个列表对象,该对象可以保存各种数据(例如,体重/身高/年龄/情绪/国家等) 这些条件相互矛盾,因为如果函数没有先验信息,它就不知道如何命名数据列。我的解决方案是通过包含一个参数来半自动化函数,该参数告诉调用函数时函数的用途 因此,因为函数在执行时知道其“目的”,所以它知道一列将包括(例如)年龄,另一列将包括
列a
,列b
,等等)tidyverse
函数解决这个问题
1—要转换的数据对象
vecI将最终解分成两个不同的函数;然而,如果你愿意的话,你可能会想把它们筑巢。另外,我去掉了目的
参数。如果完全符合您的目的,您可以将其放回:
# Load packages
library(dplyr)
# Make data
vec_driver_license <- c("F2849563", "I2938461", "B2293890")
names(vec_driver_license) <- c("626-710-9060", "831-263-9154", "510-923-6869")
data_object_phone_dl_1 <- as.list(vec_driver_license)
vec_phone_number <- c("626-710-9060", "831-263-9154", "510-923-6869")
names(vec_phone_number) <- c("F2849563", "I2938461", "B2293890")
data_object_phone_dl_2 <- as.list(vec_phone_number)
# Create custom functions
check_content <- function(x){
if(all(grepl("[\u0370-\u03ff\u1f00-\u1fff]+", x))){
out <- "greek"
} else if(all(grepl("^[A-Z]{1}\\d{7}$", x))){
out <- "driver_license"
} else if(all(grepl("^\\s*(\\+\\s*1(-?|\\s+))*[0-9]{3}\\s*-?\\s*[0-9]{3}\\s*-?\\s*[0-9]{4}$", x))){
out <- "phone_number"
} else if(all(grepl("^[A-Z]{1}\\d{7}$", x))){
out <- "driver_license_id"
} else {
out <- "undefined"
}
out
}
organize_in_table <- function(data_list){
df <- tibble::enframe(data_list) %>%
tidyr::unnest(cols = value)
colnames(df) <- purrr::map_chr(df, check_content)
df
}
# Demo with data_object_phone_dl_1
organize_in_table(data_object_phone_dl_1)
# A tibble: 3 x 2
phone_number driver_license
<chr> <chr>
1 626-710-9060 F2849563
2 831-263-9154 I2938461
3 510-923-6869 B2293890
# Demo with data_object_phone_dl_2
organize_in_table(data_object_phone_dl_2)
# A tibble: 3 x 2
driver_license phone_number
<chr> <chr>
1 F2849563 626-710-9060
2 I2938461 831-263-9154
3 B2293890 510-923-6869
#加载包
图书馆(dplyr)
#制作数据
vec_driver_license我的看法是,您应该编写一个函数,负责识别列表中的数据类型,以确定其性质。该函数将检查您提到的条件(例如,不能大于110的正整数…),然后相应地分配一个列名。如果您提到您期望的不同类型的值的示例,这里的社区可以帮助您编写适当的函数。使用已有的函数,如堆栈(my_data_object_as_list)
frombase R
或enframe(my_data_object_as_list)%%>%Unest(c(value))不是更容易些吗
使用enframe
,您还可以指定columns@SavedByJESUS--我刚刚编辑了这篇文章,提供了两个具有相关标准检查功能的用例示例。谢谢@akrun,你的建议很好,但不要解决重命名问题。我刚刚编辑了这篇文章,添加了更多我想要实现的具体演示。感谢这些功能!然而,当我试着运行organize\u in_table(data\u object\u phone\u dl\u 1)
时,它返回(通过dput()
)结构(列表(driver\u license=“F2849563”,driver\u license=“I2938461”,driver\u license=“B2293890”),row.names=c(NA,--1L),class=c(“tbl\u-df”,“tbl”,“data.frame”)
。但我无法在函数中找到更正此问题的位置。。。你有什么想法吗?这是因为我编写的函数期望在向量中接收相同类型的字符串。这就是我试图用我的数据列表
来举例说明的。因此,您应该尝试:在表中组织(vec驾驶执照)
(我明白了,data\u object\u phone\u dl\u 1
的向量对应项。但我的情况很特殊,vec\u driver\u license
没有反映出来。我的数据以data\u object\u phone\u dl\u 1
的格式到达,这意味着基本向量和叠加的名称实际上都是数据的一部分。因此,它是pai。)向量元素和包含数据的名称之间的环。这就是为什么vec\u driver\u license
不能独立存在的原因,没有附带的名称就没有意义。我指定vec\u driver\u license
只是为了使这篇文章可复制。实际上,像data\u object\u phone\u dl\u 1
这样的对象来自>json
文件。@Emman好的,我现在更明白了。我刚刚编辑了代码以满足您的需要。太棒了,这看起来很棒,谢谢!据我所知,行数据列表