![](/img/trans.png)
[英]R: df header columns are ordinal ranking and spread across columns for each observation
[英]Split/spread a DF column where differing values of for each observation
假設我有一個如下數據框:
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”下的向量中的每個不同值。
在深入探討循環和正則表達式之前,我想知道是否有人曾經遇到過這個問題,並且是否有“正確”的方法來做到這一點? 我一直在尋找tidyr的spread()函數,但是我不確定在給定每個觀察值的每個向量內字段數量不同的情況下,該方法是否適用於此。
如何處理mydf以在map_of_blah中的名稱值對及其對應值中包含其他字段?
這是str_extract
和spread
一個選項。 使用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
試試看
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映射中的所有項目分開,然后我們將其格式化為長格式。 之后,我們分離列,以便獲得兩個新的列(標題之一和值之一)。 最后,我們傳播到了廣泛的領域。
讓我知道是否有任何不清楚的地方。
這是dplyr
和tidyr
的一種方法-
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.