识别 tbl_df 列 class
Identifying a tbl_df column class
我正在将 SAS 数据集读入 R。SAS 将缺失的字符值存储为空引号,但值得庆幸的是 zap_empty()
将这些值转换为 NA。
我的数据集包含近 400 个变量,我不想单独检查每个变量。我想做一个循环来识别变量是否是一个字符,然后应用 zap_empty()
.
read_sas()
将数据导入为 tbl_df
而不是 data.frame
。如果我首先将我的数据转换为 data.frame
,则以下循环有效。
x <- as.data.frame(mydf)
for (i in seq(ncol(x))) {
if(is.character(x[,i])){
x[,i] <- zap_empty(x[,i])
}
}
我想了解如何使用 tbl_df
通过布尔测试来识别列 class。下面提供了一个示例 SAS 数据集,使用 read_sas()
从 haven
.
读取
> wolves <- read_sas('http://psych.colorado.edu/~carey/Courses/PSYC7291/DataSets/SAS/wolves.sas7bdat')
>
> # The first 3 variables are characters
> glimpse(wolves)
Observations: 25
Variables: 13
$ location (chr) "rm", "rm", "rm", "rm", "rm", "rm", "rm", "rm", "rm"...
$ wolf (chr) "rmm1", "rmm2", "rmm3", "rmm4", "rmm5", "rmm6", "rm"...
$ sex (chr) "m", "m", "m", "m", "m", "m", "f", "f", "f", "m", "m"...
$ x1 (dbl) 126, 128, 126, 125, 126, 128, 116, 120, 116, 117, 1...
$ x2 (dbl) 104, 111, 108, 109, 107, 110, 102, 103, 103, 99, 10...
$ x3 (dbl) 141, 151, 152, 141, 143, 143, 131, 130, 125, 134, 1...
$ x4 (dbl) 81.0, 80.4, 85.7, 83.1, 81.9, 80.6, 76.7, 75.1, 74....
$ x5 (dbl) 31.8, 33.8, 34.7, 34.0, 34.0, 33.0, 31.5, 30.2, 31....
$ x6 (dbl) 65.7, 69.8, 69.1, 68.0, 66.1, 65.0, 65.0, 63.8, 62....
$ x7 (dbl) 50.9, 52.7, 49.3, 48.2, 49.0, 46.4, 45.4, 44.4, 41....
$ x8 (dbl) 44.0, 43.2, 45.6, 43.8, 42.4, 40.2, 39.0, 41.1, 44....
$ x9 (dbl) 18.2, 18.5, 17.9, 18.4, 17.9, 18.2, 16.8, 16.9, 17....
$ subject (dbl) 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ...
>
> # But my loop cannot identify that
> for (i in 1:ncol(wolves)){
+ if (is.character(wolves[,i])){
+ print('bar')
+ } else {print('foo')}
+ }
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
当我使用 $
访问该列时,它被识别为一个字符,但在使用索引时却不是。
> class(wolves$sex)
[1] "character"
> class(wolves[,'sex'])
[1] "tbl_df" "data.frame"
如何使用循环来识别 tbl_df
对象中的哪些列是字符变量?
来自@Sumedh,我现在可以识别哪些列是字符。
这个错误是否意味着我不能在循环中使用 zap_empty()
?
> for (i in seq(which(sapply(wolves, class) == 'character'))){
+ wolves[,i] <- zap_empty(wolves[,i])
+ }
Show Traceback
Rerun with Debug
Error: is.character(x) is not TRUE
您需要确保在字符向量而非单列数据框上进行测试is.character(x)
。
您的 is.character(x[,i])
没有正确检查字符,因为单个括号下标总是 return 相同类型的对象。
由于x
是一个数据框,所以x[,i]
也是一个数据框。要获得字符向量,我们使用 [[1]]
到 select x[,i]
.
单列数据框中的第一个向量
x <- as.data.frame(mydf)
for (i in seq(ncol(x))) {
if(is.character(x[,i][[1]])){
x[,i] <- zap_empty(x[,i][[1]])
}
}
这在 R for Data Science 一书中有更好更彻底的解释:http://r4ds.had.co.nz/vectors.html#recursive-vectors-lists
无需循环即可执行此操作的一种方法:
character_vars <- lapply(x, class) == "character"
x[, character_vars] <- lapply(x[, character_vars], zap_empty)
我正在将 SAS 数据集读入 R。SAS 将缺失的字符值存储为空引号,但值得庆幸的是 zap_empty()
将这些值转换为 NA。
我的数据集包含近 400 个变量,我不想单独检查每个变量。我想做一个循环来识别变量是否是一个字符,然后应用 zap_empty()
.
read_sas()
将数据导入为 tbl_df
而不是 data.frame
。如果我首先将我的数据转换为 data.frame
,则以下循环有效。
x <- as.data.frame(mydf)
for (i in seq(ncol(x))) {
if(is.character(x[,i])){
x[,i] <- zap_empty(x[,i])
}
}
我想了解如何使用 tbl_df
通过布尔测试来识别列 class。下面提供了一个示例 SAS 数据集,使用 read_sas()
从 haven
.
> wolves <- read_sas('http://psych.colorado.edu/~carey/Courses/PSYC7291/DataSets/SAS/wolves.sas7bdat')
>
> # The first 3 variables are characters
> glimpse(wolves)
Observations: 25
Variables: 13
$ location (chr) "rm", "rm", "rm", "rm", "rm", "rm", "rm", "rm", "rm"...
$ wolf (chr) "rmm1", "rmm2", "rmm3", "rmm4", "rmm5", "rmm6", "rm"...
$ sex (chr) "m", "m", "m", "m", "m", "m", "f", "f", "f", "m", "m"...
$ x1 (dbl) 126, 128, 126, 125, 126, 128, 116, 120, 116, 117, 1...
$ x2 (dbl) 104, 111, 108, 109, 107, 110, 102, 103, 103, 99, 10...
$ x3 (dbl) 141, 151, 152, 141, 143, 143, 131, 130, 125, 134, 1...
$ x4 (dbl) 81.0, 80.4, 85.7, 83.1, 81.9, 80.6, 76.7, 75.1, 74....
$ x5 (dbl) 31.8, 33.8, 34.7, 34.0, 34.0, 33.0, 31.5, 30.2, 31....
$ x6 (dbl) 65.7, 69.8, 69.1, 68.0, 66.1, 65.0, 65.0, 63.8, 62....
$ x7 (dbl) 50.9, 52.7, 49.3, 48.2, 49.0, 46.4, 45.4, 44.4, 41....
$ x8 (dbl) 44.0, 43.2, 45.6, 43.8, 42.4, 40.2, 39.0, 41.1, 44....
$ x9 (dbl) 18.2, 18.5, 17.9, 18.4, 17.9, 18.2, 16.8, 16.9, 17....
$ subject (dbl) 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ...
>
> # But my loop cannot identify that
> for (i in 1:ncol(wolves)){
+ if (is.character(wolves[,i])){
+ print('bar')
+ } else {print('foo')}
+ }
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
[1] "foo"
当我使用 $
访问该列时,它被识别为一个字符,但在使用索引时却不是。
> class(wolves$sex)
[1] "character"
> class(wolves[,'sex'])
[1] "tbl_df" "data.frame"
如何使用循环来识别 tbl_df
对象中的哪些列是字符变量?
来自@Sumedh,我现在可以识别哪些列是字符。
这个错误是否意味着我不能在循环中使用 zap_empty()
?
> for (i in seq(which(sapply(wolves, class) == 'character'))){
+ wolves[,i] <- zap_empty(wolves[,i])
+ }
Show Traceback
Rerun with Debug
Error: is.character(x) is not TRUE
您需要确保在字符向量而非单列数据框上进行测试is.character(x)
。
您的 is.character(x[,i])
没有正确检查字符,因为单个括号下标总是 return 相同类型的对象。
由于x
是一个数据框,所以x[,i]
也是一个数据框。要获得字符向量,我们使用 [[1]]
到 select x[,i]
.
x <- as.data.frame(mydf)
for (i in seq(ncol(x))) {
if(is.character(x[,i][[1]])){
x[,i] <- zap_empty(x[,i][[1]])
}
}
这在 R for Data Science 一书中有更好更彻底的解释:http://r4ds.had.co.nz/vectors.html#recursive-vectors-lists
无需循环即可执行此操作的一种方法:
character_vars <- lapply(x, class) == "character"
x[, character_vars] <- lapply(x[, character_vars], zap_empty)