如何将长格式的数据框转换为适当格式的列表?
Posted
技术标签:
【中文标题】如何将长格式的数据框转换为适当格式的列表?【英文标题】:How to convert a dataframe in long format into a list of an appropriate format? 【发布时间】:2020-11-12 19:43:49 【问题描述】:我有以下长格式的数据框:
我需要将它转换成一个看起来像这样的列表:
其中,列表的每个主要元素都是“实例编号”。及其子元素应包含所有对应的参数和值对 - 格式为“参数 X”=“abc”,如您在第二张图片中看到的那样,一个接一个地列出。
是否有任何现有的功能可以做到这一点?我真的找不到任何东西。任何帮助将不胜感激。
谢谢。
【问题讨论】:
欢迎来到 ***。请花时间阅读how to provide a great pandas example 上的这篇文章以及如何提供minimal, complete, and verifiable example 并相应地修改您的问题。 how to ask a good question 上的这些提示也可能有用。 【参考方案1】:dplyr 解决方案
require(dplyr)
df_original <- data.frame("Instance No." = c(3,3,3,3,5,5,5,2,2,2,2),
"Parameter" = c("age", "workclass", "education", "occupation",
"age", "workclass", "education",
"age", "workclass", "education", "income"),
"Value" = c("Senior", "Private", "HS-grad", "Sales",
"Middle-aged", "Gov", "Hs-grad",
"Middle-aged", "Private", "Masters", "Large"),
check.names = FALSE)
# the split function requires a factor to use as the grouping variable.
# Param_Value will be the properly formated vector
df_modified <- mutate(df_original,
Param_Value = paste0(Parameter, "=", Value))
# drop the parameter and value columns now that the data is contained in Param_Value
df_modified <- select(df_modified,
`Instance No.`,
Param_Value)
# there is now a list containing dataframes with rows grouped by Instance No.
list_format <- split(df_modified,
df_modified$`Instance No.`)
# The Instance No. is still in each dataframe. Loop through each and strip the column.
list_simplified <- lapply(list_format,
select, -`Instance No.`)
# unlist the remaining Param_Value column and drop the names.
list_out <- lapply(list_simplified ,
unlist, use.names = F)
现在应该有一个按要求格式化的向量列表。
$`2`
[1] "age=Middle-aged" "workclass=Private" "education=Masters" "income=Large"
$`3`
[1] "age=Senior" "workclass=Private" "education=HS-grad" "occupation=Sales"
$`5`
[1] "age=Middle-aged" "workclass=Gov" "education=Hs-grad"
贴出来的data.table解决方案比较快,不过我觉得这样比较好理解。
【讨论】:
感谢您的回复。我在第二行代码中遇到错误。它说以下Error: Can't subset columns that don't exist. x Columns
3436108600,
8135121,
8134395,
66398212,
49332, etc. don't exist.
这不是很有帮助。抛出错误的函数的名称是什么?听起来您需要整理数据。数据框列名称是否与此处代码中的名称实际匹配?您如何处理 NA 值?
这工作得很好,就像我想要的一样!非常感谢!我没有更改数据中的任何其他内容。【参考方案2】:
require(data.table)
your_dt <- data.table(your_df)
dt_long <- melt.data.table(your_dt, id.vars='Instance No.')
class(dt_long) # for debugging
dt_long[, strVal:=paste(variable,value, sep = '=')]
result_list <- list()
for (i in unique(dt_long[['Instance No.']]))
result_list[[as.character(i)]] <- dt_long[`Instance No.`==i, strVal]
【讨论】:
感谢您的回复。以下是我在第四行得到的错误。你能帮忙看看那行代码到底是做什么的吗?:=
(strVal, paste(Parameter, Value, : 检查 is.data.table(DT) == TRUE) 中的错误。否则,:= 和 :=
(...) 被定义用于 j,一次仅以特定方式。请参阅帮助(“:=”)。
你执行了第二行吗? your_dt <- data.table(your_df)
- 有必要让它工作
是的,我做到了。它运行得非常好,直到第三行也创建了“dt_long”数据框。但是第四行给出了我提到的错误。
这很奇怪。好的,尝试使用melt.data.table()
而不是melt()
运行;之后还运行class(dt_long)
(请参阅更新的答案)并告诉我们它提供了什么
如果这不起作用,如果没有您的真实数据,我们将无法为您提供帮助。如果您可以共享表格的一个片段(作为数据,而不是图片) - 那会更有效率。要获得可重现的片段(前 10 行),请运行 dput(your_df[1:10,])
并在您的问题中分享输出。【参考方案3】:
仅供参考。这是执行此操作的 R base oneliner。 df
是您的数据框。
l <- lapply(split(df, list(df["Instance No."])),
function(x) paste0(x$Parameter, "=", x$Value))
【讨论】:
感谢您的回复。代码正在执行,但我得到一个包含所有实例编号的列表,最后是一个“=”。实际上看起来不像我想要的。但它看起来像这样: ("Instance No.1", "Instance No.2", "Instance No.3",...."=")以上是关于如何将长格式的数据框转换为适当格式的列表?的主要内容,如果未能解决你的问题,请参考以下文章