拆分/扩展DF列,其中每个观察值的值不同

时间:2019-08-06 18:08:23

标签: r

假设我有一个如下数据框:

mydf <- structure(list(club_member = c(0L, 0L, 1L, 0L, 0L, 0L), map_of_blah = c(NA, 
                                                                                 "{Upgrade=1.0}", "{Apples=0.32786885245901637, In-Game Boost=0.06557377049180328, WalkoffGm=0.08196721311475409, Improve=0.5245901639344263}", 
                                                                                 NA, 
                                                                                 "{MystBox=0.9977827050997783, Upgrade=0.0022172949002217295, Apples = 1}", 
                                                                                 NA)), row.names = c(NA, 6L), class = "data.frame")

glimpse(mydf)
Observations: 6
Variables: 2
$ club_member <int> 0, 0, 1, 0, 0, 0
$ map_of_blah <chr> NA, "{Upgrade=1.0}", "{Apples=0.32786885245901637, In-Game Boost=0.06557377049180328, WalkoffGm=0.08196721311475409, Improve=0.5245901639344263}", NA, "{MystBox=0.9977827050997783, …


mydf
  club_member                                                                                                                map_of_blah
1           0                                                                                                                       <NA>
2           0                                                                                                              {Upgrade=1.0}
3           1 {Apples=0.32786885245901637, In-Game Boost=0.06557377049180328, WalkoffGm=0.08196721311475409, Improve=0.5245901639344263}
4           0                                                                                                                       <NA>
5           0                                                    {MystBox=0.9977827050997783, Upgrade=0.0022172949002217295, Apples = 1}
6           0                                                                                                                       <NA>

我将数据直接从数据库中提取到r中,其中一种数据类型(Presto db)是其中r的数组映射。在r中,似乎已将其作为每个观察的字符向量读入。

“ map_of_blah”字段的每个矢量包含不同的值,但是数据集中总共可能有15到20个值,例如“ Apples”,“ In-Game Boost”,“ Improve”等。

我想将此字段处理为一个新的设置字段,每个字段对应于“ map_of_blah”下向量中包含的每个不同值。

在深入探讨循环和正则表达式之前,我想知道ayone之前是否曾遇到过这个问题,是否有一种“正确”的方式来做到这一点?我一直在寻找tidyr的spread()函数,但由于每个向量的每个观察场中的字段数不同,因此我不确定在这里是否适用。

如何处理mydf以在map_of_blah中的名称值对及其对应值中包含其他字段?

3 个答案:

答案 0 :(得分:3)

这是str_extractspread的一个选项。使用str_extract_all,从“ map_of_blah”中获取相关子字符串作为list列,unnest数据集,更改类型(type_convert来自readr),并将spread设置为“宽”格式

library(tidyverse)
mydf %>% 
  transmute(ID = row_number(), club_member, 
            key = str_extract_all(map_of_blah, "\\w+(?=\\=)"), 
            val = str_extract_all(map_of_blah, "(?<=\\=)[0-9.]+")) %>% 
  unnest(c(key, val)) %>%
  type_convert %>% 
  spread(key, val) %>%
  select(-"<NA>")
# A tibble: 6 x 8
#     ID club_member Apples   Boost Improve MystBox  Upgrade WalkoffGm
#  <int>       <int>  <dbl>   <dbl>   <dbl>   <dbl>    <dbl>     <dbl>
#1     1           0 NA     NA       NA      NA     NA         NA     
#2     2           0 NA     NA       NA      NA      1         NA     
#3     3           1  0.328  0.0656   0.525  NA     NA          0.0820
#4     4           0 NA     NA       NA      NA     NA         NA     
#5     5           0 NA     NA       NA       0.998  0.00222   NA     
#6     6           0 NA     NA       NA      NA     NA         NA     

答案 1 :(得分:2)

尝试一下

library(tidyverse)
mydf %>%
   rownames_to_column("ID") %>%
   mutate(map_of_blah = str_remove_all(map_of_blah, "\\{|\\}") %>% 
          str_split(., ",\\s")) %>% 
   unnest() %>%
   separate(col = map_of_blah, into = c("newcol", "newval"), sep = "=") %>%
   mutate(newcol = str_trim(newcol, "both"),
          newval = as.numeric(newval)) %>%
   spread(newcol, newval)

我们首先为用户创建一个ID,然后我们将blah映射中的所有项目分开,然后我们将其格式化为长格式。之后,我们分离列,以便获得两个新的列(标题之一和值之一)。最后,我们传播到了广阔的范围。

让我知道是否有任何不清楚的地方。

答案 2 :(得分:1)

这里是dplyrtidyr的一种方式-

mydf %>% 
  mutate(
    user_id = 1:n(), # create id for each row
    map_of_blah = gsub("\\{|\\}", "", map_of_blah) # remove {,}
  ) %>% 
  separate_rows(map_of_blah, sep = ",") %>% # separate attributes into rows
  # separate attributes into columns
  separate(map_of_blah, into = c("var", "value"), sep = "=", convert = T) %>%
  mutate(var = trimws(var)) %>% # remove white spaces at the ends
  spread(var, value) %>% 
  select(user_id, club_member, Apples:WalkoffGm)

  user_id club_member    Apples   Improve In-Game Boost   MystBox     Upgrade  WalkoffGm
1       1           0        NA        NA            NA        NA          NA         NA
2       2           0        NA        NA            NA        NA 1.000000000         NA
3       4           0        NA        NA            NA        NA          NA         NA
4       5           0 1.0000000        NA            NA 0.9977827 0.002217295         NA
5       6           0        NA        NA            NA        NA          NA         NA
6       3           1 0.3278689 0.5245902    0.06557377        NA          NA 0.08196721