将键值对散布到列中
Spreading key value pairs into columns
我遇到了以下数据争论问题。每个数据集都有多个 aValue
的值,每个 aName
的值。这可以很容易地用整洁的数据框表示。
someDatasets <- list(dataset1 = data.frame(aName = c("a", "a", "a", "b", "b"), aValue = 1:5, dataset = "ds1"),
dataset2 = data.frame(aName = c("a", "a", "a", "b", "c", "c"), aValue = (1:6)*10 , dataset = "ds2"),
dataset3 = data.frame(aName = c("a", "c", "c", "c"), aValue = (1:4)*100, dataset = "ds3"))
tidyData <- Reduce(dplyr::bind_rows, someDatasets)
我想 "spread" 将数据集变量放入单独的列中。 (由于键重复,我无法使用 tidyr::spread
创建所需的输出。)
###
# Desired output
###
# aName ds1 ds2 ds3
# a 1 10 100
# a 2 20 NA
# a 3 30 NA
# b 4 40 NA
# b 5 NA NA
# c NA 50 200
# c NA 60 300
# c NA NA 400
是否有生成所需输出的简洁方法?
ps:我知道 问题,但解决方案
dcast(melt(someDatasets, id = "aName", na.rm = TRUE), aName~value)
没有产生所需的输出,因为使用了聚合函数 length
。
正如@lukeA 和@A Handcart and Mohair 在评论中所述,您可以为数据添加额外的 ID 以避免 重复键 问题。
library(dplyr)
library(tidyr)
tidyData = bind_rows(someDatasets) %>%
group_by(dataset, aName) %>%
mutate(id = paste0(aName, 1:n())) %>%
ungroup() %>%
select(-aName)
# head(tidyData)
# Source: local data frame [6 x 3]
#
# aValue dataset id
# <dbl> <chr> <chr>
# 1 1 ds1 a1
# 2 2 ds1 a2
# 3 3 ds1 a3
# 4 4 ds1 b1
# 5 5 ds1 b2
# 6 10 ds2 a1
id
现在在每个组(数据集)中是唯一的,因此我们可以继续传播:
tidyData %>%
spread(dataset, aValue) %>%
mutate(id = substr(id, 1, 1))
# Source: local data frame [10 x 4]
#
# id ds1 ds2 ds3
# <chr> <dbl> <dbl> <dbl>
# 1 a 1 10 100
# 2 a 2 20 NA
# 3 a 3 30 NA
# 4 b 4 40 NA
# 5 b 5 NA NA
# 6 c NA 50 200
# 7 c NA 60 300
# 8 c NA NA 400
我遇到了以下数据争论问题。每个数据集都有多个 aValue
的值,每个 aName
的值。这可以很容易地用整洁的数据框表示。
someDatasets <- list(dataset1 = data.frame(aName = c("a", "a", "a", "b", "b"), aValue = 1:5, dataset = "ds1"),
dataset2 = data.frame(aName = c("a", "a", "a", "b", "c", "c"), aValue = (1:6)*10 , dataset = "ds2"),
dataset3 = data.frame(aName = c("a", "c", "c", "c"), aValue = (1:4)*100, dataset = "ds3"))
tidyData <- Reduce(dplyr::bind_rows, someDatasets)
我想 "spread" 将数据集变量放入单独的列中。 (由于键重复,我无法使用 tidyr::spread
创建所需的输出。)
###
# Desired output
###
# aName ds1 ds2 ds3
# a 1 10 100
# a 2 20 NA
# a 3 30 NA
# b 4 40 NA
# b 5 NA NA
# c NA 50 200
# c NA 60 300
# c NA NA 400
是否有生成所需输出的简洁方法?
ps:我知道
dcast(melt(someDatasets, id = "aName", na.rm = TRUE), aName~value)
没有产生所需的输出,因为使用了聚合函数 length
。
正如@lukeA 和@A Handcart and Mohair 在评论中所述,您可以为数据添加额外的 ID 以避免 重复键 问题。
library(dplyr)
library(tidyr)
tidyData = bind_rows(someDatasets) %>%
group_by(dataset, aName) %>%
mutate(id = paste0(aName, 1:n())) %>%
ungroup() %>%
select(-aName)
# head(tidyData)
# Source: local data frame [6 x 3]
#
# aValue dataset id
# <dbl> <chr> <chr>
# 1 1 ds1 a1
# 2 2 ds1 a2
# 3 3 ds1 a3
# 4 4 ds1 b1
# 5 5 ds1 b2
# 6 10 ds2 a1
id
现在在每个组(数据集)中是唯一的,因此我们可以继续传播:
tidyData %>%
spread(dataset, aValue) %>%
mutate(id = substr(id, 1, 1))
# Source: local data frame [10 x 4]
#
# id ds1 ds2 ds3
# <chr> <dbl> <dbl> <dbl>
# 1 a 1 10 100
# 2 a 2 20 NA
# 3 a 3 30 NA
# 4 b 4 40 NA
# 5 b 5 NA NA
# 6 c NA 50 200
# 7 c NA 60 300
# 8 c NA NA 400