Разделить строковый столбец на 2 столбца, один числовой, а другой дату - PullRequest
3 голосов
/ 05 апреля 2019

У меня есть фрейм данных, называемый "ценами", полученный при просмотре веб-страниц. Цель состоит в том, чтобы отслеживать ежедневные цены на акции на фондовой бирже Зимбабве.

Соскоб с сайта:

library(rvest)
library(stringr)
library(reshape2)
# Data from African Financials
url <- "https://africanfinancials.com/zimbabwe-stock-exchange-share-prices/"
prices <- url %>%
  read_html() %>%
  html_table(fill = T)
prices <- prices[[1]]

Ценовой фрейм цен:

> prices

                   Counter   PriceRTGS cents  Volume ChangeRTGS cents ChangePercent YTDPercent
1            AFDS.zw Afdis   169.75 4 Apr 19       0             0.00         0.00%     10.95%
2          ARIS.zw Ariston     2.90 4 Apr 19     572            -0.03        -1.02%     20.83%
3     ARTD.zw ART Holdings     9.20 4 Apr 19       0             0.00         0.00%      4.55%

Я бы хотел разделить столбец «PriceRTGS cents» на два столбца «Price RTGS Cents» и «Date».

Я попытался использовать приведенный ниже код, но он фиксирует день месяца 4 в столбце цен.

str_split_fixed(prices$`PriceRTGS cents`," ", 2)
colsplit(prices$`PriceRTGS cents`," ",c("Price RTGS Cents", "Date"))

Я бы хотел, чтобы вывод выглядел так:

                   Counter   Price RTGS Cents              Date         Volume ChangeRTGS cents ChangePercent YTDPercent
1            AFDS.zw Afdis             169.75         4/04/2019              0             0.00         0.00%     10.95%
2          ARIS.zw Ariston               2.90         4/04/2019            572            -0.03        -1.02%     20.83%
3     ARTD.zw ART Holdings               9.20         4/04/2019              0             0.00         0.00%      4.55%

данные dput:

structure(list(Counter = c("AFDS.zw Afdis", "ARIS.zw Ariston", 
"ARTD.zw ART Holdings", "ASUN.zw Africansun", "AXIA.zw Axia", 
"BAT.zw BAT"), `PriceRTGS cents` = c("169.75 4 Apr 19", "2.90 4 Apr 19", 
"9.20 4 Apr 19", "15.00 4 Apr 19", "35.05 4 Apr 19", "3,000.00 4 Apr 19"
), Volume = c("0", "572", "0", "0", "8,557", "0"), `ChangeRTGS cents` = c(0, 
-0.03, 0, 0, 0, 0), ChangePercent = c("0.00%", "-1.02%", "0.00%", 
"0.00%", "0.00%", "0.00%"), YTDPercent = c("10.95%", "20.83%", 
"4.55%", "50.00%", "-22.11%", "-9.09%")), row.names = c(NA, 6L
), class = "data.frame")

Ответы [ 5 ]

1 голос
/ 05 апреля 2019

Альтернатива.Разделитель (-) и форматы даты, имена столбцов могут быть изменены:

prices$Prices<-stringr::str_extract_all(prices$`PriceRTGS cents`,"\\d{1,}.*\\.\\d{1,}",simplify=T)

prices$Dates<-stringr::str_remove_all(prices$`PriceRTGS cents`,"\\d{1,}.*\\.\\d{1,} ")
prices %>% 
  select(-`PriceRTGS cents`) %>% 
  mutate(Dates=lubridate::dmy(Dates))

Результат:

               Counter Volume ChangeRTGS cents ChangePercent YTDPercent   Prices      Dates
1        AFDS.zw Afdis      0             0.00         0.00%     10.95%   169.75 2019-04-04
2      ARIS.zw Ariston    572            -0.03        -1.02%     20.83%     2.90 2019-04-04
3 ARTD.zw ART Holdings      0             0.00         0.00%      4.55%     9.20 2019-04-04
4   ASUN.zw Africansun      0             0.00         0.00%     50.00%    15.00 2019-04-04
5         AXIA.zw Axia  8,557             0.00         0.00%    -22.11%    35.05 2019-04-04
6           BAT.zw BAT      0             0.00         0.00%     -9.09% 3,000.00 2019-04-04
1 голос
/ 05 апреля 2019

Я просто скопировал и вставил ваши первые данные о ценах в текстовый редактор и изменил пробелы с помощью ";"(Я еще не видел вашу редакцию данных).

prices <- read.table("dat.txt", sep=";", header=T)

Вид «быстрого и грязного» кода, но он работает:

str_split_fixed(prices$PriceRTGS.cents," ", 2)
new_prices <- data.frame(prices$Counter, str_split_fixed(prices$PriceRTGS.cents," ", 2), prices$Volume, prices$ChangeRTGS.cents, prices$ChangePercent, prices$YTDPercent)
colnames(new_prices) <- c("Counter", "PriceRTGS_cents", "Date",  "Volume", "ChangeRTGS cents", "ChangePercent",  "YTDPercent")
new_prices$Date <- gsub("Apr", "04", new_prices$Date)
new_prices$Date <- gsub(" ", "/", new_prices$Date)
new_prices <- data.frame(prices$Counter, new_prices$PriceRTGS_cents, new_prices$Date, prices$Volume, prices$ChangeRTGS.cents, prices$ChangePercent, prices$YTDPercent)
colnames(new_prices) <- c("Counter", "PriceRTGS_cents", "Date",  "Volume", "ChangeRTGS cents", "ChangePercent",  "YTDPercent")
new_prices

Если у вас есть другие месяцы, кроме апреля', просто добавьте другие строки (например: if "Nov")

new_prices$Date <- gsub("Nov", "10", new_prices$Date)
new_prices$Date <- gsub(" ", "/", new_prices$Date)
0 голосов
/ 05 апреля 2019

Вот и все: похоже на ваше решение str_split_fixed.Он также удаляет запятые из вашей ценовой переменной, поэтому его можно привести в numeric и отформатировать столбец даты.

split_string <- str_split(prices$`PriceRTGS cents`, regex("\\s"), 2, simplify = T)

prices$Price <- as.numeric(gsub(",", "", split_string[,1], fixed = T))
prices$Date <- as.Date(split_string[,2], format = "%d %b %y")

head(prices[-2])
               Counter Volume ChangeRTGS cents ChangePercent YTDPercent   Price       Date
1        AFDS.zw Afdis      0             0.00         0.00%     10.95%  169.75 2019-04-04
2      ARIS.zw Ariston    572            -0.03        -1.02%     20.83%    2.90 2019-04-04
3 ARTD.zw ART Holdings      0             0.00         0.00%      4.55%    9.20 2019-04-04
4   ASUN.zw Africansun      0             0.00         0.00%     50.00%   15.00 2019-04-04
5         AXIA.zw Axia  8,557             0.00         0.00%    -22.11%   35.05 2019-04-04
6           BAT.zw BAT      0             0.00         0.00%     -9.09% 3000.00 2019-04-04

Проблема с фиксированным решением заключается в том, что он не распознавал пробел после цены.т.е.

0 голосов
/ 05 апреля 2019

Базовая опция R - разделить на пустое место и создать две части строки, первую часть цены, а оставшуюся часть вместе как дату.

t(sapply(strsplit(prices$`PriceRTGS cents`,"\\s+"), function(x) 
  c(x[1], format(as.Date(paste0(x[-1], collapse = "-"), "%d-%b-%y"), "%d/%m/%Y"))))

#         [,1]           [,2]        
#[1,] "169.75"   "04/04/2019"
#[2,] "2.90"     "04/04/2019"
#[3,] "9.20"     "04/04/2019"
#[4,] "15.00"    "04/04/2019"
#[5,] "35.05"    "04/04/2019"
#[6,] "3,000.00" "04/04/2019"

Затем вы можете cbind эти два столбца в исходном кадре данных.

Если вы можете оставить столбцы с датой без форматирования, мы можем отключить as.Date и format и сократить код.

t(sapply(strsplit(prices$`PriceRTGS cents`,"\\s+"), function(x) 
             c(x[1], paste0(x[-1], collapse = "-"))))
0 голосов
/ 05 апреля 2019

вы можете сделать что-то это-

library(data.table)
setDT(dt)
dt[,Date:=sub("^\\S+\\s+", "\\1", `PriceRTGS cents`)]
dt[,cents:=sub("^\\s*(\\S+\\S+).*", "\\1", `PriceRTGS cents`)]

Примечание - Удалить исходный столбец позже из dt

> dt <- subset(dt,select = -c(`PriceRTGS cents`))
> dt
                Counter Volume ChangeRTGS cents ChangePercent YTDPercent    cents     Date
1:        AFDS.zw Afdis      0             0.00         0.00%     10.95%   169.75 4 Apr 19
2:      ARIS.zw Ariston    572            -0.03        -1.02%     20.83%     2.90 4 Apr 19
3: ARTD.zw ART Holdings      0             0.00         0.00%      4.55%     9.20 4 Apr 19
4:   ASUN.zw Africansun      0             0.00         0.00%     50.00%    15.00 4 Apr 19
5:         AXIA.zw Axia  8,557             0.00         0.00%    -22.11%    35.05 4 Apr 19
6:           BAT.zw BAT      0             0.00         0.00%     -9.09% 3,000.00 4 Apr 19

РЕДАКТИРОВАТЬ - Если вы хотите Date, как вы упомянули, то сделайте это -

dt[,Date:=format(as.Date(sub("^\\S+\\s+", "\\1", `PriceRTGS cents`),format='%d %b %Y'),"%d/%m/%Y")]
...