R Spread Data Frame基于行名
R Spread Data Frame based on row names
我有一个包含两列的数据框。行名称被复制为具有一些公共字段的报告列表中的数据圆顶。每个报告包含不同数量的字段。我想根据这些重复的行名称之一将此数据框扩展到多个列中。最终结果会使每份报告成行。
这些报告来自工作系统中存在的 API。它 returns 非常嵌套 JSON。我想看看将数据转换为这种格式是否会为我提供一种清理数据的方法。
最小数据示例
Column1 Column2
contentID 123
value1 California
value2 truck
value3 home
contentID 897
value1 Georgia
value2 car
value3 work
value4 boeing
contentID 537
value2 truck
value4 private
value5 first class
value6 wheels
期望的结果
ContentID value1 value2 value3 value4 value5 value6
123 California truck home NA NA NA
897 Georgia car work boeing NA NA
537 NA truck NA private firstclass wheels
一个 tidyverse
可能性是:
df %>%
mutate(id = cumsum(grepl("content", Column1))) %>%
group_by(id) %>%
mutate(ContentID = first(Column2)) %>%
filter(!grepl("content", Column1)) %>%
ungroup() %>%
select(-id) %>%
spread(Column1, Column2)
ContentID value1 value2 value3 value4 value5 value6
<chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 123 California truck home <NA> <NA> <NA>
2 537 <NA> truck <NA> private first_class wheels
3 897 Georgia car work boeing <NA> <NA>
在这里,它首先根据 content
在 "Column1" 中的出现创建一个 ID 变量,并按它分组。其次,它创建了一个 "ContentID" 变量,其中包含每组 "Column2" 第一行的值。第三,过滤掉"Column1"中包含content
的行。最后,它传播了数据。
你可以简单地这样做-
library(data.table)
library(zoo)
setDT(dt)
dt[,id:=ifelse(Column1 %like% "contentID",paste(Column2),NA)]
dt[,id:=na.locf(id)]
dcast.data.table(dt,id~Column1,value.var="Column2",subset = .(Column1!="contentID"))
id value1 value2 value3 value4 value5 value6
1: 123 California truck home <NA> <NA> <NA>
2: 537 <NA> truck <NA> private firstclass wheels
3: 897 Georgia car work boeing <NA> <NA>
注意- 如果你有大数据集,效率会更高。
我有一个包含两列的数据框。行名称被复制为具有一些公共字段的报告列表中的数据圆顶。每个报告包含不同数量的字段。我想根据这些重复的行名称之一将此数据框扩展到多个列中。最终结果会使每份报告成行。
这些报告来自工作系统中存在的 API。它 returns 非常嵌套 JSON。我想看看将数据转换为这种格式是否会为我提供一种清理数据的方法。
最小数据示例
Column1 Column2
contentID 123
value1 California
value2 truck
value3 home
contentID 897
value1 Georgia
value2 car
value3 work
value4 boeing
contentID 537
value2 truck
value4 private
value5 first class
value6 wheels
期望的结果
ContentID value1 value2 value3 value4 value5 value6
123 California truck home NA NA NA
897 Georgia car work boeing NA NA
537 NA truck NA private firstclass wheels
一个 tidyverse
可能性是:
df %>%
mutate(id = cumsum(grepl("content", Column1))) %>%
group_by(id) %>%
mutate(ContentID = first(Column2)) %>%
filter(!grepl("content", Column1)) %>%
ungroup() %>%
select(-id) %>%
spread(Column1, Column2)
ContentID value1 value2 value3 value4 value5 value6
<chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 123 California truck home <NA> <NA> <NA>
2 537 <NA> truck <NA> private first_class wheels
3 897 Georgia car work boeing <NA> <NA>
在这里,它首先根据 content
在 "Column1" 中的出现创建一个 ID 变量,并按它分组。其次,它创建了一个 "ContentID" 变量,其中包含每组 "Column2" 第一行的值。第三,过滤掉"Column1"中包含content
的行。最后,它传播了数据。
你可以简单地这样做-
library(data.table)
library(zoo)
setDT(dt)
dt[,id:=ifelse(Column1 %like% "contentID",paste(Column2),NA)]
dt[,id:=na.locf(id)]
dcast.data.table(dt,id~Column1,value.var="Column2",subset = .(Column1!="contentID"))
id value1 value2 value3 value4 value5 value6
1: 123 California truck home <NA> <NA> <NA>
2: 537 <NA> truck <NA> private firstclass wheels
3: 897 Georgia car work boeing <NA> <NA>
注意- 如果你有大数据集,效率会更高。