首页 > 解决方案 > R使用字符串作为列名将字符串拆分为列,并使用任何数字作为这些列中的值

问题描述

我有以下数据框:

df1 = data.frame(id = 1:4, desc=c("httpmethod=put&hobbies=22.33&utiliites=50.00&home=950.00&entertainment=40.00&redirecturl=&stamp=5%0D%0A++++", "httpmethod=put&hobbies=&utiliites=&home=600.00&entertainment=25.57&redirecturl=&stamp=5%0D%0A++++", "httpmethod=put&hobbies=0.00&utiliites=&home=1127.53&entertainment=50.00&redirecturl=&stamp=5%0D%0A++++", "httpmethod=put&hobbies=&utiliites=&home=&entertainment=&redirecturl=&stamp=5%0D%0A++++"), stringsAsFactors=FALSE)

这使:

ID 描述
1 httpmethod=put&hobbies=22.33&utiliites=50.00&home=950.00&entertainment=40.00&redirecturl=&stamp=5%0D%0A++++
2 httpmethod=put&hobbies=&utiliites=&home=600.00&entertainment=25.57&redirecturl=&stamp=5%0D%0A++++
3 httpmethod=put&hobbies=0.00&utiliites=&home=1127.53&entertainment=50.00&redirecturl=&stamp=5%0D%0A++++
4 httpmethod=put&hobbies=&utiliites=&home=&entertainment=&redirecturl=&stamp=5%0D%0A++++

我想要:

ID 爱好 公用事业 娱乐
1 22.33 50.00 950.00 40.00
2 不适用 不适用 600.00 25.57
3 0.00 不适用 1127.53 50.00
4 不适用 不适用 不适用 不适用

我看过很多不同的东西,但似乎无法将它们结合在一起。我目前拥有的代码如下,但我认为必须有一种更简单/更有说服力的方式(例如从字符串中获取列名)。

library(dplyr)
library(tidyr)
library(stringr)

df2 <- df1 %>% 
  separate(desc, c("http","hob", "utl", "hom", "ent", "redirect", "stamp"), sep = "&") %>% 
  mutate(hobbies = str_extract(hob, "\\d+\\.*\\d*")) %>%
  mutate(utilities = str_extract(utl, "\\d+\\.*\\d*")) %>%
  mutate(home = str_extract(hom, "\\d+\\.*\\d*")) %>%
  mutate(entertainment = str_extract(ent, "\\d+\\.*\\d*")) %>%
  select(-c("http","redirect", "stamp"))

我对 R 很陌生,所以对这些步骤进行一些解释会很好。我确实到了将它们拆分的地步,但最终得到了一个列表,并且不知道该怎么做才能将这些值从列表中取出。

谢谢

标签: rdataframedplyr

解决方案


hobbies0.00=如上所述更正第三行后,

library(dplyr)
library(tidyr)
df1 %>% 
    separate(col = desc, into = c("http", "hobbies", "utiliites", "home", "entertainment", "redirecturl", "stamp"), sep = "&[a-z]+[0\\.]*=") %>% 
    select(-http, -redirecturl, -stamp)
  id hobbies utiliites    home entertainment
1  1   22.33     50.00  950.00         40.00
2  2                    600.00         25.57
3  3    0.00           1127.53         50.00
4  4                                        

更新

一些修改。感谢 Shawn Brar 的评论,让我们一起来as.numeric。第二个,避免指定into向量(但必须删除一些奇怪的列):

df1 %>% 
    separate(col = desc, into = strsplit(df1$desc[1], split = "=.*?&")[[1]], sep = "&[a-z]+=") %>% 
    select(-httpmethod, -redirecturl, -`stamp=5%0D%0A++++`) %>% 
    mutate(across(everything(), as.numeric))

  id hobbies utiliites    home entertainment
1  1   22.33        50  950.00         40.00
2  2      NA        NA  600.00         25.57
3  3    0.00        NA 1127.53         50.00
4  4      NA        NA      NA            NA

推荐阅读