r-Ho运行一个函数(多次)来更改全局环境中的变量(tibble)



我是R的新手,所以请耐心等待。。。建议是最受欢迎的。

我的目标是创建一个包含"全名"(一个人,可能有2到4个名字(和他/她的性别的tibble。我必须从一个包含典型男性和女性名字的tibble开始。

下面我介绍一个最低限度的工作示例。

我的问题是:我可以多次调用get_name()(在10.000内循环!!(并得到正确的答案。但是,我一直在寻找一种更"优雅"的方法。不幸的是,replicate()返回了一个向量。。。这使得它无法使用。

我的疑虑:我知道我有一些(很少……对吧!!(问题,比如if语句,每次都会进行评估(这是多余的(,但我找不到其他方法。有什么建议吗?

也欢迎对代码结构提出任何其他建议。

事先非常感谢你的帮助。

# Dummy name list
unit_names <- tribble(
~Women, ~Man,
"fem1", "male1",
"fem2", "male2", 
"fem3", "male3",
"fem4", "male4",
"fem5", "male5",
"fem6", NA,
"fem7", NA
)
set.seed(12345) # seed for test
# Create a tibble with the full names
full_name <- tibble("Full Name" = character(), "Gender" = character() )
get_name <- function() {
# Get the Number of 'Unit-names' to compose a 'Full-name'
nbr_names <- sample(2:4, 1, replace = TRUE)
# Randomize the Gender
gender  <- sample(c("Women", "Man"), 1, replace = TRUE)
if (gender == "Women") {
lim_names <- sum( !is.na(unit_names$"Women"))
} else {
lim_names <- sum( !is.na(unit_names$"Man"))
}
# Sample the Fem/Man List names (may have duplicate)
sample(unlist(unit_names[1:lim_names, gender]), nbr_names, replace = TRUE) %>%
# Form a Full-name
paste ( . , collapse = " ") %>%
# Add it to the tibble (INCLUDE the Gender)
add_row(full_name, "Full Name" = . , "Gender" = gender)
}
# How can I make 10k of this?
full_name <- get_name()

如果将大于1的数字传递给sample,则此问题将更容易矢量化。

目前让你的问题更加困难的一件事是unit_names表的布局:你有效地将男性和女性名称视为单独配对,但它们显然不是:因此它们不应该在同一个表的列中。使用两个矢量的列表,例如:

unit_names = list(
Women = c("fem1", "fem2", "fem3", "fem4", "fem5", "fem6", "fem7"),
Men = c("male1", "male2", "male3", "male4", "male5")
)

然后,你可以生成让你高兴的随机名称:

generate_names = function (n, unit_names) {
name_length = sample(2 : 4, n, replace = TRUE)
genders = sample(c('Women', 'Men'), n, replace = TRUE)
names = Map(sample, unit_names[genders], name_length, replace = TRUE) %>%
lapply(paste, collapse = ' ') %>%
unlist()
tibble(`Full name` = names, Gender = genders)
}

注意风格,与您的函数不同,上面的函数不使用任何全局变量。此外,不要"引用"变量名(可以在unit_names$"Women"add_row的参数中这样做(。R允许这样做,但这可以说是语言规范中的一个错误:这些是而不是字符串,它们是变量名,让它们看起来像字符串会产生误导。毕竟,您不会引用其他变量名。您确实需要在`Full name`列名后面加引号,因为它包含一个空格。但是,使用反引号而不是引号表示这是一个变量名。

我不是你想要的100%,但如果我做对了。。。你在dplyr试过变异吗?例如:result= mutate(data.frame, concated_column = paste(column1, column2, column3, column4, sep = '_'))

在Konrad Rudolph的帮助下,我正在寻找以下优雅(且矢量化…且快速(的解决方案。CCD_ 11起到了必要的作用。

如果有人需要,下面是完整的工作示例:(只是附带说明:我保留了从tibble到list的初始转换,因为数据以tibble的形式到达我手中…(

再次感谢康拉德。

# Dummy name list
unit_names <- tribble(
~Women, ~Men,
"fem1", "male1",
"fem2", "male2", 
"fem3", "male3",
"fem4", "male4",
"fem5", "male5",
"fem6", NA,
"fem7", NA
)
name_list <- list(
Women = unit_names$Women[!is.na(unit_names$Women)],
Men = unit_names$Men[!is.na(unit_names$Men)]
)
generate_names = function (n, name_list) {
name_length = sample(2 : 4, n, replace = TRUE)
genders = sample(c('Women', 'Men'), n, replace = TRUE)
#names = lapply(name_list[genders], sample,  name_length) %>%
names = map2(name_list[genders], name_length, sample) %>%
lapply(paste, collapse = ' ') %>%
unlist()
tibble(`Full name` = names, Gender = genders)
}
full_name <- generate_names(10000, name_list)

最新更新