Отделяйте миллионы и миллиарды данных из одного столбца - PullRequest
0 голосов
/ 26 октября 2018

Я пытаюсь ниже код для разделения "M" и "B" с их значениями в 2 разных столбцах.

Я хочу вывод, как это:

level 1    level 2
M 3.2      B 3.6
M 4        B 2.8
           B 3.5

Ввод:

reve=c("M 3.2","B 3.6","B 2.8","B 3.5","M 4")
#class(reve)
data=data.frame(reve)

Вот что я пробовал.

index=which(grepl("M ",data$reve)
data$reve=gsub("M ","",data$reve)
data$reve=gsub("B ","",data$reve)

data$reve=as.numeric(data$reve)

Ответы [ 4 ]

0 голосов
/ 26 октября 2018

Я думаю, что опции, основанные на регулярном выражении, также могут быть полезны для этих типов проблем

 reve=c("M 3.2","B 3.6","B 2.8","B 3.5","M 4")

 data=data.frame(reve, stringsAsFactors = F) # handle your data as strings, not factors

 # regex to extract M vals and B vals
 mvals <- stringi::stri_extract_all_regex(data, "M+\\s[0-9]\\.[0-9]|M+\\s[0-9]")[[1]]
 bvals <- stringi::stri_extract_all_regex(data, "B+\\s[0-9]\\.[0-9]|B+\\s[0-9]")[[1]]

 # gluing things together into a single df
 len <- max(length(mvals), length(bvals)) # find the length
 data.frame(M = c(mvals, rep(NA, len - length(mvals))) # ensure vectors are the same size
           ,B = c(bvals, rep(NA, len - length(bvals)))) # ensure vectors are the same size

В случае, если регулярное выражение незнакомо, первое выражение ищет «M», затем пробел, затем цифры 0до 9, затем точка, затем снова цифры от 0 до 9.Вертикальный канал находится в операторе «или», поэтому выражение также ищет «M», затем пробел, а затем цифры от 0 до 9. Вторая половина выражения учитывает случаи, подобные «M 4».Второе выражение делает то же самое, только для строк, которые содержат «B» вместо «M».

Это быстрые и грязные выражения регулярных выражений.Я уверен, что более чистые составы позволяют получить те же результаты.

0 голосов
/ 26 октября 2018

Если у вас есть фрейм данных, вы можете сделать это с помощью dplyr Отдельный ()

Я приведу вам пример этого:

library(dplyr)
df <- tibble(coupe = c("M 2.3", "M 4.5", "B 1"))
df %>% separate(coupe, c("MorB","Quant"), " ")

OUTPUT

#  MorB  Quant
#  <chr> <chr>
#1 M     2.3  
#2 M     4.5  
#3 B     1    

Надеюсь, это поможет вам!

Для подсчета количества строк "M":

 df %>% separate(YourColumn, c("MorB","Quant"), " ") %>% 
 filter(MorB == "M") %>% nrow() 
0 голосов
/ 26 октября 2018

Мы можем считать Миллионы или Миллиарды следующим образом:

Входной набор данных:

reve=c("M 3.2","B 3.6","B 2.8","B 3.5","M 4")
data=data.frame(reve)

Код

library(dplyr)
library(tidyr)
data %>% 
  separate(reve, c("Label", "Value"),extra = "merge") %>%
  group_by(Label) %>% 
  summarise(n = n())

Выход

# A tibble: 2 x 2
 Label     n
  <chr> <int>
 1 B         3
 2 M         2
0 голосов
/ 26 октября 2018

Вот подход base R.

lst <- split(reve, substr(reve, 1, 1))
df1 <- as.data.frame(lapply(lst, `length<-`, max(lengths(lst))))
df1
#      B     M
#1 B 3.6 M 3.2
#2 B 2.8   M 4
#3 B 3.5  <NA>

split вектор пополам по первой букве. Это дает вам список с записями неравной длины. Используйте lapply для создания записей одинаковой длины, то есть добавьте более короткую запись с NA s. Звоните as.data.frame.

Если вы хотите изменить имена, вы можете использовать setNames

setNames(df1, c("level_2", "level_1"))

В случае, если я неправильно понял ваш желаемый результат, попробуйте

df1 <- data.frame(do.call(rbind, (strsplit(reve, " "))), stringsAsFactors = FALSE)
df1[] <- lapply(df1, type.convert, as.is = TRUE)
df1
#  X1  X2
#1  M 3.2
#2  B 3.6
#3  B 2.8
#4  B 3.5
#5  M 4.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...