使用tidyr:spread()来调整键值变量对

时间:2015-07-16 11:05:51

标签: r pivot tidyr spread

我正在尝试使用tidyr:spread()来调整键值变量对。

id <- c(0,1,2,3,4,5,6,7,8,9)
key1 <- c("a", "a", "b", "b", "c","a", "a", "b", "b", "c")
val1 <- c(1,2,3,1,2,3,1,2,3,1)
key2 <- c("d",NA,NA,NA,"e","d","d",NA,"b",NA)
val2 <- c(1,NA,NA,NA,2,3,NA,NA,3,NA)
key3 <- c("x",NA,NA,NA,"e","d",NA,NA,NA,NA)
val3 <- c(0,NA,NA,NA,NA,3,1,NA,NA,NA)
df = data.frame(id, key1, val1, key2, val2, key3, val3) 
library(tidyr)
c1 <- spread(df, key1, val1, fill = 0, convert = FALSE)
c2 <- spread(c1, key2, val2, fill = 0, convert = FALSE)
c3 <- spread(c2, key3, val3, fill = 0, convert = FALSE) 

在运行spread()时,我收到以下错误:

  

[.data.frame(数据,setdiff(名称(数据),c(key_col,   value_col))):选择了未定义的列

这让我觉得问题在于值而不是在变量名称中,正如错误所暗示的那样,任何想法都需要寻找什么?

基于同样的原因,是否有更多语法有效的方式来传播多对键值变量?

1 个答案:

答案 0 :(得分:3)

您可以使用Map

library(tidyr)
res <- do.call(cbind,Map(function(x,y) {x1 <- data.frame(x,y)
        r1 <- spread(x1, x,y, fill=0, convert=FALSE)
        r1[!is.na(names(r1))] }, 
   df[-1][c(TRUE,FALSE)], df[-1][c(FALSE, TRUE)]))

names(res) <- sub('.*\\.', '', names(res))
cbind(df, res)