我从中向R导入数据的平台不支持指定数据类型,因此我的所有列都是字符
。我有一个Excel文件,指定哪些列是因子
,包括相关的标签
和级别
。现在,我正在尝试编写一个函数来动态更改数据中各个列的数据类型。框架
多亏了对这个问题的出色回答(dplyr-mutate:use dynamic variable names),我成功地编写了以下函数,在其中我动态地将列名设置为mutate
函数。
readFactorData <- function(filepath) {
t <- read.xlsx(filepath)
sapply(nrow(t), function(i) {
colname <- as.character(t[i, "Item"])
factorLevels <- t[i, 3:ncol(t)][which(!is.na(t[i, 3:ncol(t)]))]
totalLevels <- length(factorLevels)
listOfLabels <- as.character(unlist(factorLevels))
mutate(d, !!colname := factor(d[[colname]], labels=(1:totalLevels), levels=listOfLabels))
# requires dplyr v.0.7+
# the syntax `!!variablename:=` forces evaluation of the variablename before evaluating the rest of the function
})
}
它起作用了,每次迭代都会返回整个数据帧,相关列(colname
)更改为因子。但是,每次迭代都会覆盖之前的迭代,所以这个函数只返回i
的最后一个结果。如何确保最终只有1个数据帧,其中保存了所有相关列?
示例数据(确保注释掉上面函数的第一行,因为我们在这里定义了t
):
d <- data.frame("id" = sample(100:999, 10), "age" = sample(18:80, 10), "factor1" = c(rep("a", 3), rep("b", 3), rep("c", 4)), "factor2" = c("x","y","y","y","y","x","x","x","x","y"), stringsAsFactors = FALSE)
t <- data.frame("Item" = c("factor1","factor2"), "Label" = c("This is factor 1", "This is factor 2"), "level1" = c("a","x"), "level2" = c("b","y"), "level3" = c("c","NA"))
下面的函数通过为要更改的每个命名列指定的readr::parse_*
函数进行映射,然后允许您为每个列指定参数(例如,如果使用parse_factor
,则级别
)。
library(tidyverse)
parse_cols <- function(df, f, col_names, levels, ...){
# df: dataframe, f: char vec, col_names: char vec, levels: list of char vecs,
# ...: list of other potential args for parse_*
params_t <- tibble(x = map(col_names, ~df[[.x]]), levels = levels, ...) %>% transpose()
new_cols <- map2_df(.x = structure(f, names = col_names),
.y = params_t,
~R.utils::doCall(.x, args = .y, .ignoreUnusedArgs = TRUE))
df[names(new_cols)] <- new_cols
df
}
# function inputs -- perhaps just requiring a tibble input would be safer
parsings_vec <- c("parse_factor","parse_double", "parse_factor")
cols_vec <- c("manufacturer", "cty", "class")
factors_list <- list(unique(mpg[["manufacturer"]]), NULL, unique(mpg[["class"]]))
parse_cols(df = mpg, f = parsings_vec, col_names = cols_vec, levels = factors_list)
#> # A tibble: 234 x 11
#> manufacturer model displ year cyl trans drv cty hwy fl cla~
#> <fct> <chr> <dbl> <int> <int> <chr> <chr> <dbl> <int> <chr> <fc>
#> 1 audi a4 1.8 1999 4 auto~ f 18 29 p com~
#> 2 audi a4 1.8 1999 4 manu~ f 21 29 p com~
#> 3 audi a4 2 2008 4 manu~ f 20 31 p com~
#> 4 audi a4 2 2008 4 auto~ f 21 30 p com~
#> 5 audi a4 2.8 1999 6 auto~ f 16 26 p com~
#> 6 audi a4 2.8 1999 6 manu~ f 18 26 p com~
#> 7 audi a4 3.1 2008 6 auto~ f 18 27 p com~
#> 8 audi a4 q~ 1.8 1999 4 manu~ 4 18 26 p com~
#> 9 audi a4 q~ 1.8 1999 4 auto~ 4 16 25 p com~
#> 10 audi a4 q~ 2 2008 4 manu~ 4 20 28 p com~
#> # ... with 224 more rows
如果你想转换你所有的因素
到字符
在你的data.frame
你可以使用dplyr
的mutate_if
。否则,如果你想使用列名的向量,@Eden Z的答案会帮你。
library(tidyverse)
d_out <- d %>%
mutate_if(is.character, as.factor)
d_out
# id age factor1 factor2
#1 933 61 a x
#2 208 52 a y
#3 193 25 a y
#4 231 47 b y
#5 595 78 b y
#6 675 28 b x
#7 387 71 c x
#8 386 80 c x
#9 893 20 c x
#10 272 23 c y
当您可以检查类中的变量时:
sapply(d_out, class)
# id age factor1 factor2
#"integer" "integer" "factor" "factor"
如果我理解正确,你有一个数据帧,另一个数据帧的因子列值。你想从第一个df中提取这些,并在第二个df中变异这些列,并将它们转化为因子。
保留列名的向量,然后对它们进行变异怎么样?
colnames <- t %>%
pull(Item) %>%
as.character()
d_with_factors <- d %>%
mutate_at(colnames, as.factor)
然后呢
sapply(d_with_factors, class)
返回
id age factor1 factor2
"integer" "integer" "factor" "factor"
问题内容: 我正在尝试更改derby db列的数据类型。当前价格列设置为DECIMAL(5,0)。我想将其更改为DECIMAL(7,2)。我是这样做的: 但是它不起作用,并显示错误: 我可以知道如何进行更改吗?谢谢你。 问题答案: 这是Derby SQL脚本,用于将列MY_TABLE.MY_COLUMN从BLOB(255)更改为BLOB(2147483647):
问题内容: 我想将多列的数据类型从float更改为int。最简单的方法是什么? 尚无数据可担心。 问题答案: http://dev.mysql.com/doc/refman/5.1/en/alter- table.html 这将更改给定列的数据类型 根据您希望修改的列数,最好生成一个脚本或使用某种mysql客户端GUI
我现在正在开发一个系统,该系统将表的主键定义为“int”,这个主键有一个规则序列:“yearmonthmonth”6个数字。例如:“2105000001”,但“22”(2022)的年份没有被预测,或者,如果我将序列的这种模式调整到当前年份,它将给出一个错误,因为它超过了最大值。质疑:这个系统非常庞大,在java、postgresql数据库中,切换到Long的利弊是什么?它会对数据库性能产生类似的影
问题内容: 我想将表示为列表列表的表转换为。作为一个极其简化的示例: 将列转换为适当类型的最佳方法是什么(在这种情况下,将列2和3转换为浮点数)?有没有一种方法可以在转换为DataFrame时指定类型?还是先创建DataFrame然后遍历各列以更改各列的类型更好?理想情况下,我想以动态方式执行此操作,因为可以有数百个列,并且我不想确切指定哪些列属于哪种类型。我可以保证的是,每一列都包含相同类型的值
问题内容: 我有一个Spring应用程序,我想动态更改数据源。当输入DS URL时,Spring Bean和所有依赖项将自动更新。我知道这有些奇怪,但是无论如何我都想实现。我的Spring配置如下: 问题是: JDBC URL存储在属性中,可以在运行时更改它。 更改URL后,我需要重新创建数据源,可能还需要重新创建相关对象。我不知道Spring如何优雅地做呢? 我知道Spring确实可以基于一个键
我有一个Spring应用程序,我想动态更改数据源,即。当输入DS URL时,Spring bean和所有依赖项将自动更新。我知道这有点奇怪,但无论如何我想实现这一点。我的Spring配置如下: 问题是: > 一旦URL被更改,我需要重新创建数据源,可能还有依赖对象。我不知道如何在Spring优雅地做这件事? 我知道Spring可以基于一个键动态路由数据源,但数据源URL是在Spring中预定义的,