如何将字符串矩阵转换为小标题?
How can I convert a matrix of strings into a tibble?
我在 .rData 文件中得到了一些数据。在字符模式下,格式是 xts
object。 (我知道这是一种不寻常的格式,但我无法控制它)
> head(trades)
SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
2012-05-04 09:30:00 "BAC" "T" "7.89" "38538" "F" "7.89" "523" "7.9"
2012-05-04 09:30:01 "BAC" "Z" "7.885" "288" "@" "7.88" "61033" "7.9"
2012-05-04 09:30:03 "BAC" "X" "7.89" "1000" "@" "7.88" "1974" "7.89"
2012-05-04 09:30:07 "BAC" "T" "7.89" "19052" "F" "7.88" "1058" "7.89"
2012-05-04 09:30:08 "BAC" "Y" "7.89" "85053" "F" "7.88" "108101" "7.9"
2012-05-04 09:30:09 "BAC" "D" "7.8901" "10219" "@" "7.89" "268" "7.9"
> mode(trades)
'character'
我想通过转换成更合理的格式(即 tibble)来处理这些数据,以便我可以将列存储为日期时间、双精度和整数。
我已经通过以下代码实现了这一点:
> trades_ = bind_cols(data_frame(DATE=index(trades)), as_data_frame(coredata(trades))) %>%
mutate_at(as.numeric, .cols=vars(PRICE, BID, OFR)) %>%
mutate_at(as.integer, .cols=vars(SIZE, BIDSIZ, OFRSIZ))
> head(trades_)
# A tibble: 6 × 10
DATE SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
<dttm> <chr> <chr> <dbl> <int> <chr> <dbl> <int> <dbl>
1 2012-05-04 09:30:00 BAC T 7.8900 38538 F 7.89 523 7.90
2 2012-05-04 09:30:01 BAC Z 7.8850 288 @ 7.88 61033 7.90
3 2012-05-04 09:30:03 BAC X 7.8900 1000 @ 7.88 1974 7.89
4 2012-05-04 09:30:07 BAC T 7.8900 19052 F 7.88 1058 7.89
5 2012-05-04 09:30:08 BAC Y 7.8900 85053 F 7.88 108101 7.90
6 2012-05-04 09:30:09 BAC D 7.8901 10219 @ 7.89 268 7.90
我想知道是否已经有一个 built-in 函数用于此。查看 trades
矩阵的每一列并确定它是否是整数列、双精度列等并将其转换为适当类型的东西。
这是 csv 解析器会做的事情。
这远非权威答案,但我最终这样做了:
smarter_type_convert = function (vector) {
converted_vector = type.convert(vector)
if (is.numeric(converted_vector)) {
int_vector = as.integer(converted_vector)
if (isTRUE(all.equal(int_vector, converted_vector, check.attributes=FALSE))) {
int_vector
} else {
converted_vector
}
} else {
converted_vector
}
}
trades %>% coredata %>% as_data_frame %>% mutate_all(smarter_type_convert)
你说得对,数据框是正确的方法,因为你在同一帧中处理多个 classes。 xts
不允许多个 classes,因此强制转换规则会强制您使用字符而不是数字。
这里有一个解决方案,因此您不必特别指出每一列。我使用 tidyquant
包,它是为处理 "tidyverse" 中的定量数据而制作的(即使用 "tidy" 数据框)。它还具有一些很好的函数,可以在 xts
、matrix
和其他包含行名称的时间序列 class 之间进行转换。
首先,我重新创建数据。
> trades_xts
SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
2012-05-04 09:30:00 "BAC" "T" "7.8900" "38538" "F" "7.89" "523" "7.90"
2012-05-04 09:30:01 "BAC" "Z" "7.8850" "288" "@" "7.88" "61033" "7.90"
2012-05-04 09:30:03 "BAC" "X" "7.8900" "1000" "@" "7.88" "1974" "7.89"
2012-05-04 09:30:07 "BAC" "T" "7.8900" "19052" "F" "7.88" "1058" "7.89"
2012-05-04 09:30:08 "BAC" "Y" "7.8900" "85053" "F" "7.88" "108101" "7.90"
2012-05-04 09:30:09 "BAC" "D" "7.8901" "10219" "@" "7.89" "268" "7.90"
接下来,我使用 tidy 函数来清理数据。它比您的脚本稍长,但您无需担心哪些列具有哪种数据类型(xts 索引除外)。请注意,我正在使用 tidyquant::as_tibble()
函数将 xts
行名称转换为列。我使用 mutate_each
将 type.convert
函数应用于每一列。不幸的是,基础 R 喜欢 factor
class,所以我添加了一个额外的步骤来转换为 character
。最后两个步骤只是使用 dplyr::rename
和 lubridate::as_datetime
清理日期时间列,tidyquant
为您加载。
> library(tidyquant)
> trades_xts %>%
as_tibble(preserve_row_names = TRUE) %>%
mutate_each(funs(type.convert)) %>%
mutate_if(is.factor, as.character) %>%
rename(DATE = row.names) %>%
mutate(DATE = as_datetime(DATE, tz = Sys.timezone()))
# A tibble: 6 × 9
DATE SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
<dttm> <chr> <chr> <dbl> <int> <chr> <dbl> <int> <dbl>
1 2012-05-04 09:30:00 BAC T 7.8900 38538 F 7.89 523 7.90
2 2012-05-04 09:30:01 BAC Z 7.8850 288 @ 7.88 61033 7.90
3 2012-05-04 09:30:03 BAC X 7.8900 1000 @ 7.88 1974 7.89
4 2012-05-04 09:30:07 BAC T 7.8900 19052 F 7.88 1058 7.89
5 2012-05-04 09:30:08 BAC Y 7.8900 85053 F 7.88 108101 7.90
6 2012-05-04 09:30:09 BAC D 7.8901 10219 @ 7.89 268 7.90
我在 .rData 文件中得到了一些数据。在字符模式下,格式是 xts
object。 (我知道这是一种不寻常的格式,但我无法控制它)
> head(trades)
SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
2012-05-04 09:30:00 "BAC" "T" "7.89" "38538" "F" "7.89" "523" "7.9"
2012-05-04 09:30:01 "BAC" "Z" "7.885" "288" "@" "7.88" "61033" "7.9"
2012-05-04 09:30:03 "BAC" "X" "7.89" "1000" "@" "7.88" "1974" "7.89"
2012-05-04 09:30:07 "BAC" "T" "7.89" "19052" "F" "7.88" "1058" "7.89"
2012-05-04 09:30:08 "BAC" "Y" "7.89" "85053" "F" "7.88" "108101" "7.9"
2012-05-04 09:30:09 "BAC" "D" "7.8901" "10219" "@" "7.89" "268" "7.9"
> mode(trades)
'character'
我想通过转换成更合理的格式(即 tibble)来处理这些数据,以便我可以将列存储为日期时间、双精度和整数。
我已经通过以下代码实现了这一点:
> trades_ = bind_cols(data_frame(DATE=index(trades)), as_data_frame(coredata(trades))) %>%
mutate_at(as.numeric, .cols=vars(PRICE, BID, OFR)) %>%
mutate_at(as.integer, .cols=vars(SIZE, BIDSIZ, OFRSIZ))
> head(trades_)
# A tibble: 6 × 10
DATE SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
<dttm> <chr> <chr> <dbl> <int> <chr> <dbl> <int> <dbl>
1 2012-05-04 09:30:00 BAC T 7.8900 38538 F 7.89 523 7.90
2 2012-05-04 09:30:01 BAC Z 7.8850 288 @ 7.88 61033 7.90
3 2012-05-04 09:30:03 BAC X 7.8900 1000 @ 7.88 1974 7.89
4 2012-05-04 09:30:07 BAC T 7.8900 19052 F 7.88 1058 7.89
5 2012-05-04 09:30:08 BAC Y 7.8900 85053 F 7.88 108101 7.90
6 2012-05-04 09:30:09 BAC D 7.8901 10219 @ 7.89 268 7.90
我想知道是否已经有一个 built-in 函数用于此。查看 trades
矩阵的每一列并确定它是否是整数列、双精度列等并将其转换为适当类型的东西。
这是 csv 解析器会做的事情。
这远非权威答案,但我最终这样做了:
smarter_type_convert = function (vector) {
converted_vector = type.convert(vector)
if (is.numeric(converted_vector)) {
int_vector = as.integer(converted_vector)
if (isTRUE(all.equal(int_vector, converted_vector, check.attributes=FALSE))) {
int_vector
} else {
converted_vector
}
} else {
converted_vector
}
}
trades %>% coredata %>% as_data_frame %>% mutate_all(smarter_type_convert)
你说得对,数据框是正确的方法,因为你在同一帧中处理多个 classes。 xts
不允许多个 classes,因此强制转换规则会强制您使用字符而不是数字。
这里有一个解决方案,因此您不必特别指出每一列。我使用 tidyquant
包,它是为处理 "tidyverse" 中的定量数据而制作的(即使用 "tidy" 数据框)。它还具有一些很好的函数,可以在 xts
、matrix
和其他包含行名称的时间序列 class 之间进行转换。
首先,我重新创建数据。
> trades_xts
SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
2012-05-04 09:30:00 "BAC" "T" "7.8900" "38538" "F" "7.89" "523" "7.90"
2012-05-04 09:30:01 "BAC" "Z" "7.8850" "288" "@" "7.88" "61033" "7.90"
2012-05-04 09:30:03 "BAC" "X" "7.8900" "1000" "@" "7.88" "1974" "7.89"
2012-05-04 09:30:07 "BAC" "T" "7.8900" "19052" "F" "7.88" "1058" "7.89"
2012-05-04 09:30:08 "BAC" "Y" "7.8900" "85053" "F" "7.88" "108101" "7.90"
2012-05-04 09:30:09 "BAC" "D" "7.8901" "10219" "@" "7.89" "268" "7.90"
接下来,我使用 tidy 函数来清理数据。它比您的脚本稍长,但您无需担心哪些列具有哪种数据类型(xts 索引除外)。请注意,我正在使用 tidyquant::as_tibble()
函数将 xts
行名称转换为列。我使用 mutate_each
将 type.convert
函数应用于每一列。不幸的是,基础 R 喜欢 factor
class,所以我添加了一个额外的步骤来转换为 character
。最后两个步骤只是使用 dplyr::rename
和 lubridate::as_datetime
清理日期时间列,tidyquant
为您加载。
> library(tidyquant)
> trades_xts %>%
as_tibble(preserve_row_names = TRUE) %>%
mutate_each(funs(type.convert)) %>%
mutate_if(is.factor, as.character) %>%
rename(DATE = row.names) %>%
mutate(DATE = as_datetime(DATE, tz = Sys.timezone()))
# A tibble: 6 × 9
DATE SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
<dttm> <chr> <chr> <dbl> <int> <chr> <dbl> <int> <dbl>
1 2012-05-04 09:30:00 BAC T 7.8900 38538 F 7.89 523 7.90
2 2012-05-04 09:30:01 BAC Z 7.8850 288 @ 7.88 61033 7.90
3 2012-05-04 09:30:03 BAC X 7.8900 1000 @ 7.88 1974 7.89
4 2012-05-04 09:30:07 BAC T 7.8900 19052 F 7.88 1058 7.89
5 2012-05-04 09:30:08 BAC Y 7.8900 85053 F 7.88 108101 7.90
6 2012-05-04 09:30:09 BAC D 7.8901 10219 @ 7.89 268 7.90