Str*_* on 2 for-loop r dataframe
我有一个数据争论问题,我真的无法理解。我曾遇到过将数据粘在一长串中的情况,其中包括几个人的姓名和性别。我想从这些字符串中挑选出特定的信息并将它们放在一个数据框中。我已经设法做到了这一点,但我的解决方案远非优雅,如果可以循环遍历变量和数据框而不是使用我庞大的解决方案,那就太好了。我无法共享原始数据,但我创建了一个示例数据。数据遵循以下结构:
\ndf <- data.frame(Movie=c("Matrix", "Black Widow"), \n People=c("\xc2\xa4\xc2\xa4\xc2\xa434543\xc2\xa4Keanu Reeves\xc2\xa4932 9273\xc2\xa4Male\xc2\xa4\xc2\xa4\xc2\xa402734\xc2\xa4Laurence Fishburne\xc2\xa4936 2740\xc2\xa4Male\xc2\xa4\xc2\xa4\xc2\xa447622\xc2\xa4Carrie-Anne Moss\xc2\xa4938 0722\xc2\xa4Female\xc2\xa4\xc2\xa4\xc2\xa421539\xc2\xa4Hugo Weaving\xc2\xa4953 6124\xc2\xa4Male",\n "\xc2\xa4\xc2\xa4\xc2\xa498237\xc2\xa4Scarlett Johansson\xc2\xa4923 8734\xc2\xa4Female\xc2\xa4\xc2\xa4\xc2\xa472367\xc2\xa4Florence Pugh\xc2\xa4732 4284\xc2\xa4Female\xc2\xa4\xc2\xa4\xc2\xa455661\xc2\xa4David Harbour\xc2\xa4981 2469\xc2\xa4Male"))\nRun Code Online (Sandbox Code Playgroud)\n最后,我想得到以下数据框:
\n# Movie Name Sex\n#1 Matrix Keanu Reeves Male\n#2 Black Widow Scarlett Johansson Female\n#3 Matrix Laurence Fishburne Male\n#4 Black Widow Florence Pugh Female\n#5 Matrix Carrie-Anne Moss Female\n#6 Black Widow David Harbour Male\n#7 Matrix Hugo Weaving Male\nRun Code Online (Sandbox Code Playgroud)\n好的,这是我的解决方案:
\n我首先计算分隔字符的出现次数,然后将数据分成几部分:''
\nlibrary(stringr)\ndf$people_count <- str_count(df$People, "\xc2\xa4")\n\nmax_people_count <- max(df$people_count)\n\nnew_varnames <- paste0("Name", 0:max_people_count)\ndf[c(new_varnames)] <- str_split_fixed(df$People, "\xc2\xa4", max_people_count+1)\nRun Code Online (Sandbox Code Playgroud)\n我想选择第 1、8 和 10 列,并将第 8 和 10 列重命名为“姓名”和“性别”。然后我想从第 8 列和第 10 列开始,每隔 6 个与第 1 列一起选择。我的解决方案是创建新的数据框,重命名选定的列,最后将所有内容重新组合在一起:
\ncol_select <- c(8, 10)\n\ndf1 <- df[ , c(1, col_select)]\ncolnames(df1)[2] ="Name"\ncolnames(df1)[3] ="Sex"\n\n\n\ncol_select <- col_select+6\ndf2 <- df[ , c(1, col_select)]\ncolnames(df2)[2] ="Name"\ncolnames(df2)[3] ="Sex"\n\ncol_select <- col_select+6\ndf3 <- df[ , c(1, col_select)]\ncolnames(df3)[2] ="Name"\ncolnames(df3)[3] ="Sex"\n\ncol_select <- col_select+6\ndf4 <- df[ , c(1, col_select)]\ncolnames(df4)[2] ="Name"\ncolnames(df4)[3] ="Sex"\n\n\nfinal_df <- rbind(df1, df2, df3, df4)\n\nfinal_df <- subset(final_df, Name != "") # remove blank lines\nRun Code Online (Sandbox Code Playgroud)\n如您所见,我的 R 技能有限。必须有一种方法可以循环执行此操作。我的问题是我无法在工作 for 循环中创建数据帧的名称。如果我能做到这一点,我就不必一遍又一遍地重复相同的行,只需更改数据框的名称(请注意,我的原始数据要大得多)。
\n我真的很感谢对这个问题的帮助,因为我正在努力学习如何有效地使用 R。
\nYou don\'t need an explicit loop.
\nIn base R you can use strsplit to split the useful parts of each string into a vector once we have found the pattern of the unwanted characters in between. Each vector can then be converted to a data frame inside lapply. The resulting list of data frames can then be Mapped to the appropriate movie from your original data set. Finally, the resultant lists of data frames can all be joined together using do.call("rbind", ...)
do.call(\'rbind\',\n Map(\\(x, y) cbind(Movie = x, y), df$Movie, df$People |>\n strsplit(\'\xc2\xa4\xc2\xa4\xc2\xa4\\\\d+\xc2\xa4|\xc2\xa4\\\\d+ \\\\d+\xc2\xa4\') |>\n lapply(\\(x) as.data.frame(t(matrix(x[-1], nrow = 2))) |>\n setNames(c(\'Name\', \'Sex\'))))) |>\n `rownames<-`(NULL)\n#> Movie Name Sex\n#> 1 Matrix Keanu Reeves Male\n#> 2 Matrix Laurence Fishburne Male\n#> 3 Matrix Carrie-Anne Moss Female\n#> 4 Matrix Hugo Weaving Male\n#> 5 Black Widow Scarlett Johansson Female\n#> 6 Black Widow Florence Pugh Female\n#> 7 Black Widow David Harbour Male\nRun Code Online (Sandbox Code Playgroud)\n如您所见,这适用于您的示例数据框。然而,此类字符串解析高度依赖于确切的输入,因此尚不清楚这是否适用于您的实际数据。
\n| 归档时间: |
|
| 查看次数: |
72 次 |
| 最近记录: |