Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用从R上的另一列提取的信息创建新列_R_String_Dplyr_Tidyverse_Extract - Fatal编程技术网

使用从R上的另一列提取的信息创建新列

使用从R上的另一列提取的信息创建新列,r,string,dplyr,tidyverse,extract,R,String,Dplyr,Tidyverse,Extract,我有一个数据框,其中一列有多个信息,以“;”分隔,如下所示: DF = data.frame(a = c(1,1,1,2,2), b = c('aaa','aaa','aba','abc','ccc'), extra_info = c( 'animal=horse;color=orange;shape=circle', 'animal=monkey;shape=square;value=53

我有一个数据框,其中一列有多个信息,以“;”分隔,如下所示:

DF = data.frame(a = c(1,1,1,2,2), b = c('aaa','aaa','aba','abc','ccc'), 
                extra_info = c(
                  'animal=horse;color=orange;shape=circle',
                  'animal=monkey;shape=square;value=532',
                  'animal=horse;color=blue;shape=square;value=321',
                  'animal=dog;color=green;value=678',
                  'color=pink;shape=triangle'
                ))
我不能使用read.table,因为我已经在使用不同的函数来读取数据(而且列extra_info中的每一行的内容都不一样,而且这些列会被弄乱)。我想做的是将所有这些信息分离到不同的列中,并相应地指定专有名称,例如:

a   b   animal  color   shape    value
1  aaa  horse   orange  circle   NA
1  aaa  monkey  NA      square   532
1  aba  horse   blue    square   321
2  abc  dog     green   NA       678
2  ccc  NA      pink    triangle NA
到目前为止,我已经尝试:

new_cols = DF %>% separate(extra_info, c(LETTERS[1:4]), sep = ";")

new_cols %>% separate(A, c("key","value"), sep = '=') %>% 
  separate(B, c("key","value"), sep = '=') %>%
  separate(C, c("key","value"), sep = '=') %>%
  separate(D, c("key","value"), sep = '=') %>%
  pivot_wider(names_from = c("key"), values_from = c("value"))

但是它并没有像预期的那样工作。

使用stringr软件包有点整洁,但是如果您只需要base R,您可以使用以下工具。在
模式中
结构
(?%

mutate(color=str_extract(extra_info),(?这里有一种方法,我将键值对的语法更改为有效的JSON语法,并使用
jsonlite::fromJSON
解析它:

library(purrr)
library(dplyr)
library(stringr)
library(jsonlite)
DF %>%
  mutate(
    json = str_replace_all(extra_info, pattern = "\\b", replacement = '"'),
    json = str_replace_all(json, pattern = fixed("="), replacement = ":"),
    json = str_replace_all(json, pattern = fixed(";"), replacement = ","),
    json = paste("{", json, "}"),
  ) %>%
  pull(json) %>%
  map(jsonlite::fromJSON) %>%
  map(as.data.frame) %>%
  bind_rows %>%
  cbind(DF, .)
#   a   b                                     extra_info animal  color    shape value
# 1 1 aaa         animal=horse;color=orange;shape=circle  horse orange   circle  <NA>
# 2 1 aaa           animal=monkey;shape=square;value=532 monkey   <NA>   square   532
# 3 1 aba animal=horse;color=blue;shape=square;value=321  horse   blue   square   321
# 4 2 abc               animal=dog;color=green;value=678    dog  green     <NA>   678
# 5 2 ccc                      color=pink;shape=triangle   <NA>   pink triangle  <NA>
库(purrr)
图书馆(dplyr)
图书馆(stringr)
图书馆(jsonlite)
DF%>%
变异(
json=str_replace_all(额外信息,pattern=“\\b”,replacement=”),
json=str_replace_all(json,pattern=fixed(“=”),replacement=“:”,
json=str_replace_all(json,pattern=fixed(“;”),replacement=“,”,
json=粘贴(“{”,json,“}”),
) %>%
拉入(json)%>%
映射(jsonlite::fromJSON)%>%
映射(作为.data.frame)%>%
绑定_行%>%
cbind(DF,.)
#a b额外信息动物颜色形状值
#1 aaa动物=马;颜色=橙色;形状=圆圈马橙色圆圈
#2 1 aaa动物=猴子;形状=正方形;值=532猴子正方形532
#3 1 aba动物=马;颜色=蓝色;形状=正方形;值=321马蓝色正方形321
#4 2 abc动物=狗;颜色=绿色;值=678狗绿色678
#5.2 ccc颜色=粉红色;形状=三角形粉红色三角形
库(stringr)
col_名称%

mutate(animal=str_extract(extra_info,paste0)((?这里是一个使用
gsub
+
eval
+
str2表达式的基本R选项

v <- DF$extra_info
p <- gsub(";", ",", gsub("(?<=\\=)(\\w+)", "'\\1'", v, perl = TRUE))
nms <- unique(unlist(regmatches(v, gregexpr("\\w+(?=\\=)", v, perl = TRUE))))
q <- unname(Map(function(x) setNames(eval(str2expression(x))[nms], nms), sprintf("c(%s)", p)))
cbind(DF[c("a","b")], type.convert(data.frame(do.call(rbind, q)), as.is = TRUE))

v查看
tidyr::separate
。这将为您拆分
上的列。然后运行每一列并对其进行分析。如果您需要更多帮助,请提供一个。感谢您的评论。我尝试了separate,效果非常好,尽管我不知道可能出现的所有信息类型,所以在某些列中有一个不匹配。实际上,您可能可以使用
分隔两次
。一次用于
,一次用于所有结果列,在
=
上拆分以分隔为键列和值列。然后您可以使用
透视_更宽
将键和值透视到每个键的单独列中。我理解这些步骤,但我不知道aven还没有弄明白如何实现它。我编辑了这篇文章,我认为它现在更容易理解和复制。非常感谢您的帮助!优雅的
fromJSON
解决方案!投票赞成!哦,我从这条路线开始,但有点卡住了,切换到了JSON。
str2expression
是一个很好的实用程序。这是我最喜欢的工具lution,因为它是以R为基数的,并且是可推广的(我确实有比4更多的列,而且我也不知道所有的列)。然而,我无法在我的数据bc中使用它,我没有涵盖我的示例中可能出现的所有情况(对此我表示歉意)。在现实生活中,我有带空格、逗号、{}的字符串和十进制数。我可以通过用u替换空格和逗号来绕过它们,但我想知道我们是否可以修改RE,使其包含带-,{}和十进制数的大小写。我只是问bc我对RE不太熟悉,但我正在尝试这样做。”可能有一种很好的方法可以在四个单词上写一个循环“是的,我认为这是一个很好的通用解决方案所必需的。我的假设是OP用一个只有4个单词的玩具例子来分享,但是可能还有更多的……
library(purrr)
library(dplyr)
library(stringr)
library(jsonlite)
DF %>%
  mutate(
    json = str_replace_all(extra_info, pattern = "\\b", replacement = '"'),
    json = str_replace_all(json, pattern = fixed("="), replacement = ":"),
    json = str_replace_all(json, pattern = fixed(";"), replacement = ","),
    json = paste("{", json, "}"),
  ) %>%
  pull(json) %>%
  map(jsonlite::fromJSON) %>%
  map(as.data.frame) %>%
  bind_rows %>%
  cbind(DF, .)
#   a   b                                     extra_info animal  color    shape value
# 1 1 aaa         animal=horse;color=orange;shape=circle  horse orange   circle  <NA>
# 2 1 aaa           animal=monkey;shape=square;value=532 monkey   <NA>   square   532
# 3 1 aba animal=horse;color=blue;shape=square;value=321  horse   blue   square   321
# 4 2 abc               animal=dog;color=green;value=678    dog  green     <NA>   678
# 5 2 ccc                      color=pink;shape=triangle   <NA>   pink triangle  <NA>
library(stringr) 
col_names <- unlist(str_extract_all(DF$extra_info[3], "(?<=^|;)\\w+"))
DF %>% 
  mutate(animal =  str_extract(extra_info, paste0("(?<=", col_names[1], "=)\\w+")),
         color = str_extract(extra_info, paste0("(?<=", col_names[2], "=)\\w+")), 
         shape = str_extract(extra_info, paste0("(?<=", col_names[3], "=)\\w+")),
         value = str_extract(extra_info, paste0("(?<=", col_names[4], "=)\\w+"))
  a   b                                     extra_info animal  color    shape value
1 1 aaa         animal=horse;color=orange;shape=circle  horse orange   circle  <NA>
2 1 aaa           animal=monkey;shape=square;value=532 monkey   <NA>   square   532
3 1 aba animal=horse;color=blue;shape=square;value=321  horse   blue   square   321
4 2 abc               animal=dog;color=green;value=678    dog  green     <NA>   678
5 2 ccc                      color=pink;shape=triangle   <NA>   pink triangle  <NA>
v <- DF$extra_info
p <- gsub(";", ",", gsub("(?<=\\=)(\\w+)", "'\\1'", v, perl = TRUE))
nms <- unique(unlist(regmatches(v, gregexpr("\\w+(?=\\=)", v, perl = TRUE))))
q <- unname(Map(function(x) setNames(eval(str2expression(x))[nms], nms), sprintf("c(%s)", p)))
cbind(DF[c("a","b")], type.convert(data.frame(do.call(rbind, q)), as.is = TRUE))
  a   b animal  color    shape value
1 1 aaa  horse orange   circle    NA
2 1 aaa monkey   <NA>   square   532
3 1 aba  horse   blue   square   321
4 2 abc    dog  green     <NA>   678
5 2 ccc   <NA>   pink triangle    NA