【问题标题】:Spreading keys/values over multiple data frames stored in a list using a for loop使用 for 循环将键/值分布在存储在列表中的多个数据帧上
【发布时间】:2018-07-18 09:27:21
【问题描述】:

我有一堆数据帧存储在一个列表中。我的目标是格式化列表中的每个数据框,以便特定列中的值变成列名。由于我希望转换列表中的每个数据框,因此我尝试将tidyverse 中的spread 函数应用于列表中的所有元素。但是,我收到以下错误:

the condition has length > 1 and only the first element will be usedError:  `var` must evaluate to a single number or a column name, not a double vector

这是我从How to control new variables' names after tidyr's spread? 借来的一个虚拟示例,以方便讨论:

创建虚拟数据框:

df1 <- data.frame(
    id = rep(1:3, rep(2,3)), 
    year = rep(c(2012, 2013), 3), 
    value = runif(6)
)

df2 <- data.frame(
    id = rep(4:6, rep(2,3)), 
    year = rep(c(2012, 2013), 3), 
    value = runif(6)
)

将数据框存储在列表中:

list <- list(df1, df2)

list[[1]]
#  id year      value
#1  1 2012 0.09668064
#2  1 2013 0.62739399
#3  2 2012 0.45618433
#4  2 2013 0.60347152
#5  3 2012 0.84537624
#6  3 2013 0.33466030

list[[1]] 的期望结果:

#  id       2012      2013
#1  1 0.09668064 0.6273940
#2  2 0.45618433 0.6034715
#3  3 0.84537624 0.3346603

我尝试将键/值分布在作为元素存储在列表中的所有数据帧上:

library(tidyverse)
for (i in 1:2){
  list[[i]] %>% spread(key = list[[i]][,2], value = list[[i]][,3])
}

【问题讨论】:

  • library(tidyr); lapply(list, function(x) spread(x, year, value)) 我假设你不坚持for循环。
  • @markus 谢谢!有没有办法使用索引而不是它们的名称来引用列?在我的实际数据集valuespread(x, year, value) 因数据帧而异。
  • 麻糬,很高兴我能帮上忙。如果解决了您的问题,请考虑接受@akrun 的回答。

标签: r for-loop tidyr tidyverse


【解决方案1】:

最好不要为key/value 使用索引,因为列顺序的任何更改都会产生错误的结果w,但如果位置已知,那么

library(tidyverse)
res <- map(list, ~ .x %>% 
                     spread(key = 2, value = 3))

与作为列名传递的键/值进行比较。我们建议使用名称

resOld <- map(list, ~ .x %>% 
                        spread(key = year, value = value))
identical(res, resOld)
#[1] TRUE

【讨论】:

    猜你喜欢
    • 2022-11-26
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    相关资源
    最近更新 更多