Могу ли я разделить персонажа запятыми? - PullRequest
3 голосов
/ 05 марта 2020

Предположим, у меня есть dd, и я хочу разделить столбец cc и, наконец, получить цель tdd.

> dd <- tibble(aa=c("we","dd","qw"),
+              cc=c("de,34,ff,55u,gf,55","de,34","de,34,ff,55u"))
> dd
# A tibble: 3 x 2
  aa    cc                
  <chr> <chr>             
1 we    de,34,ff,55u,gf,55
2 dd    de,34             
3 qw    de,34,ff,55u      
> targetdd <- tibble(aa=c("we","we","we","dd","qw","qw"),
+                    cc= c("de,34","ff,55u","gf,55","de,34","de,34","ff,55u"))
> targetdd
# A tibble: 6 x 2
  aa    cc    
  <chr> <chr> 
1 we    de,34 
2 we    ff,55u
3 we    gf,55 
4 dd    de,34 
5 qw    de,34 
6 qw    ff,55u

Предположим, у меня есть дд и я хочу разделить столбец cc и, наконец, получить цель tdd.

Ответы [ 6 ]

6 голосов
/ 05 марта 2020

используя положительный прогноз мы можем разделить на , с последующей буквой

library(dplyr)
dd %>% tidyr::separate_rows(cc, sep = ",(?=[a-z]+)")
# A tibble: 6 x 2
  aa    cc    
  <chr> <chr> 
1 we    de,34 
2 we    ff,55u
3 we    gf,55 
4 dd    de,34 
5 qw    de,34 
6 qw    ff,55u
5 голосов
/ 05 марта 2020

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

library(dplyr)

tidyr::separate_rows(dd, cc, sep = ",") %>%
  group_by(aa) %>%
  group_by(gr = rep(row_number(), each  =2, length.out = n()), add = TRUE) %>%
  summarise(cc = toString(cc)) %>%
  select(-gr)

#   aa    cc     
#  <chr> <chr>  
#1 dd    de, 34 
#2 qw    de, 34 
#3 qw    ff, 55u
#4 we    de, 34 
#5 we    ff, 55u
#6 we    gf, 55 
2 голосов
/ 05 марта 2020

Использование strsplit. (Regex заимствовано у @ A. Suliman.)

do.call(rbind.data.frame, Map(cbind, dd$aa, strsplit(dd$cc, ",(?=[a-z]+)", perl=T)))
#      V1     V2
# we.1 we  de,34
# we.2 we ff,55u
# we.3 we  gf,55
# dd   dd  de,34
# qw.1 qw  de,34
# qw.2 qw ff,55u
2 голосов
/ 05 марта 2020
dd %>% 
 mutate(res = purrr::map(cc, ~ tibble(cc_new = unlist(stringr::str_split(.x, ",(?=[a-z]+)"))))) %>% 
 unnest(res)

# A tibble: 6 x 3
  aa    cc                 cc_new
  <chr> <chr>              <chr> 
1 we    de,34,ff,55u,gf,55 de,34 
2 we    de,34,ff,55u,gf,55 ff,55u
3 we    de,34,ff,55u,gf,55 gf,55 
4 dd    de,34              de,34 
5 qw    de,34,ff,55u       de,34 
6 qw    de,34,ff,55u       ff,55u
1 голос
/ 05 марта 2020

Базовый раствор R:

# Split the string into groups: 
cc_uld <- lapply(strsplit(dd$cc, ","), function(x){
      x <- unlist(strsplit(paste0(ifelse(grepl("\\d+", x), 
                                  paste0(x, ","), x), collapse = " "), ","))
    }
  )

# Replicate aa vector by the length of cc_uld list elements:
rolled_out_df <- data.frame(aa = rep(as.character(dd$aa), sapply(cc_uld, length)), 
                            cc = unlist(cc_uld), stringsAsFactors = FALSE)

# Prep the string to mirror the target:
rolled_out_df$cc <- gsub("\\s+", ",", trimws(rolled_out_df$cc, "both"))
0 голосов
/ 05 марта 2020

Обобщенное решение для split_every_kth - вхождение sep в str ing:

nGroup_indexes <- function(vec, n) {
  vec_len <- length(vec)
  index_groups <- list()
  for (i in seq(n)) {
    index_groups[[i]] <- seq(from=i, to=vec_len, by=n)
  }
  index_groups
  suppressWarnings(index_mat <- Reduce(cbind, index_groups))
  colnames(index_mat) <- 1:n
  divisor <- vec_len %% n
  if (!(divisor * n == vec_len)) {
    index_mat[vec_len %/% n + 1, (vec_len %% n + 1):n] <- NA
  }
  index_mat
}

nGroups <- function(vec, n) {
  index_mat <- nGroup_indexes(vec, n)
  res <- lapply(1:nrow(index_mat), function(row_idx) vec[index_mat[row_idx, ]])
  res[[nrow(index_mat)]] <- na.omit(res[[nrow(index_mat)]])
  res
}

split_every_kth <- function(str, sep, k) {
  i_res <- strsplit(str, sep)[[1]]
  grouped_i_res <- nGroups(i_res, k)
  groups_joined <- lapply(grouped_i_res, function(vec) paste(vec, collapse=sep))
  unlist(groups_joined) # make back to vector
}

# > split_every_kth("a,b,c,d,e,f,g", ",", 2)
# [1] "a,b" "c,d" "e,f" "g"
# > split_every_kth("a,b,c,d,e,f,g", ",", 3)
# [1] "a,b,c" "d,e,f" "g"  

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...