R:在平移列中使用strsplit

问题描述 投票:0回答:3

我有一个小标题,其中一列是字符串。它们是被调查者表示演奏的乐器的名称。我想捕获每个乐器,因为它是各自独立的字符串。此列中的值范围从单个字符串(如吉他)到更复杂的答案:唱歌,鼓/打击乐,钢琴/键盘...等我已经尝试过这样的事情:

options <- strsplit(survey$instruments_list, "\\, | \\/ | ")

遗憾的是,输出在几个字符串之间仍然具有/字符。

也是最后一个问题,其中一个受访者回答的答案冗长,令人难以置信,而且答案之间用多个空格隔开,我只想要乐器,而不是他们的生活故事。

任何建议将不胜感激,谢谢!编辑:dput(head(survey))的结果

structure(list(time_submitted = c("8/27/19 20:22", "8/29/19 12:15", 
"8/28/19 19:33", "8/29/19 16:25", "8/27/19 15:40", "8/27/19 22:59"
), pseudonym_generator = c("Fake rapper name generator", "Fake band name generator", 
"Fake band name generator", "Fake band name generator", "Fake band name generator", 
"Fake band name generator"), pseudonym = c("Lord Los Angeles", 
"Heroes War", "Puppets War", "West Magic", "Eller Angel", "Trace Stripes"
), sex = c("Male", "Male", "Male", "Male", "Male", "Male"), academic_major = c("Computer Science", 
"Computer Science", "Math", "Computer Science", "Computer Science", 
"Computer Science"), academic_level = c("Senior", "Junior", "Senior", 
"Junior", "Senior", "Senior"), year_born = c(1994, 1997, 1996, 
1999, 1998, 1986), instrument_list = c("Rap", "Guitar", "Guitar", 
"Trumpet", "Piano/Keyboards, Ukulele", NA), favorite_song_artist = c("40 crew", 
"Arctic Monkeys", "Avatar", "Ben Folds", "blink-182", "brian jonestown massacre / sarabeth tucek"
), favorite_song = c("Not Enough", "Arabella", "The Eagle Has Landed", 
"Still", "She's Out Of Her Mind", "Seer"), favorite_song_link = c("https://www.youtube.com/watch?v=uITuGZKljgQ", 
"https://www.youtube.com/watch?v=Jn6-TItCazo", "https://www.youtube.com/watch?v=4p6GWewmTYQ", 
"https://www.youtube.com/watch?v=ShBzUK4rnI8", "https://www.youtube.com/watch?v=krpm0v_486k", 
"https://youtu.be/C-XT7DZsNP8")), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -6L))
r tibble strsplit
3个回答
1
投票

怎么样:

library(dplyr)
library(tidyr)
survey %>%
  transmute(pseudonym, inst = strsplit(instrument_list, "[,/]")) %>%
  filter(!is.na(inst)) %>%
  unnest() %>%
  mutate(inst = trimws(inst), plays = TRUE) %>%
  spread(inst, plays) %>%
  mutate_at(vars(-pseudonym), Negate(is.na))
# # A tibble: 5 x 7
#   pseudonym        Guitar Keyboards Piano Rap   Trumpet Ukulele
#   <chr>            <lgl>  <lgl>     <lgl> <lgl> <lgl>   <lgl>  
# 1 Eller Angel      FALSE  TRUE      TRUE  FALSE FALSE   TRUE   
# 2 Heroes War       TRUE   FALSE     FALSE FALSE FALSE   FALSE  
# 3 Lord Los Angeles FALSE  FALSE     FALSE TRUE  FALSE   FALSE  
# 4 Puppets War      TRUE   FALSE     FALSE FALSE FALSE   FALSE  
# 5 West Magic       FALSE  FALSE     FALSE FALSE TRUE    FALSE  

0
投票

我们也可以使用cSplit_e中的splitstackshape

output <- splitstackshape::cSplit_e(survey, "instrument_list", type = "character", 
                 fill = 0, sep=",|/", fixed = FALSE)

output[12:17]
#  instrument_list_Guitar instrument_list_Keyboards instrument_list_Piano
#1                      0                         0                     0
#2                      1                         0                     0
#3                      1                         0                     0
#4                      0                         0                     0
#5                      0                         1                     1
#6                      0                         0                     0

#  instrument_list_Rap instrument_list_Trumpet instrument_list_Ukulele
#1                   1                       0                       0
#2                   0                       0                       0
#3                   0                       0                       0
#4                   0                       1                       0
#5                   0                       0                       1
#6                   0                       0                       0

此列中的1表示正在演奏乐器,0表示未演奏。


0
投票

与其他答案没有太大不同,但这是使用某些tidyr便利性的答案。 separate_rows拆分字符串并在一次调用中取消嵌套;如果在正则表达式中包含可选的\\s,则", "中的空格将包含在分隔符中,因此您可以跳过修剪空白。添加一个虚拟变量会提供一个值来填充工具栏,NA会用0填充。

library(dplyr)
library(tidyr)

survey_wide <- survey %>%
  select(pseudonym, instrument_list) %>%
  separate_rows(instrument_list, sep = "(\\,|\\/)\\s?") %>%
  filter(!is.na(instrument_list)) %>%
  mutate(dummy = 1) %>%
  spread(key = instrument_list, value = dummy, fill = 0) 

survey_wide
#> # A tibble: 5 x 7
#>   pseudonym        Guitar Keyboards Piano   Rap Trumpet Ukulele
#>   <chr>             <dbl>     <dbl> <dbl> <dbl>   <dbl>   <dbl>
#> 1 Eller Angel           0         1     1     0       0       1
#> 2 Heroes War            1         0     0     0       0       0
#> 3 Lord Los Angeles      0         0     0     1       0       0
#> 4 Puppets War           1         0     0     0       0       0
#> 5 West Magic            0         0     0     0       1       0

如果需要布尔值而不是数字,这是一个附加步骤:

survey_wide %>%
  mutate_at(vars(-pseudonym), as.logical)
#> # A tibble: 5 x 7
#>   pseudonym        Guitar Keyboards Piano Rap   Trumpet Ukulele
#>   <chr>            <lgl>  <lgl>     <lgl> <lgl> <lgl>   <lgl>  
#> 1 Eller Angel      FALSE  TRUE      TRUE  FALSE FALSE   TRUE   
#> 2 Heroes War       TRUE   FALSE     FALSE FALSE FALSE   FALSE  
#> 3 Lord Los Angeles FALSE  FALSE     FALSE TRUE  FALSE   FALSE  
#> 4 Puppets War      TRUE   FALSE     FALSE FALSE FALSE   FALSE  
#> 5 West Magic       FALSE  FALSE     FALSE FALSE TRUE    FALSE
© www.soinside.com 2019 - 2024. All rights reserved.