如何将长格式的数据框转换为适当格式的列表?

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 &lt;- 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",...."=")

以上是关于如何将长格式的数据框转换为适当格式的列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何将长整数时间转换为 NSString 或 NSDate 以显示时间?

熊猫数据框到 json 列表格式

如何将长文本文件字段放入列表框?

如何将以下数据框转换为特定格式?

将熊猫数据框转换为具有以下格式的excel

如何将调查熊猫数据框转换为可用于 Python 中的 BI 工具的不同格式?