【问题标题】:How to convert a dataframe in long format into a list of an appropriate format?如何将长格式的数据框转换为适当格式的列表?
【发布时间】:2020-11-12 19:43:49
【问题描述】:

我有以下长格式的数据框:

我需要将它转换成一个看起来像这样的列表:

其中,列表的每个主要元素都是“实例编号”。及其子元素应包含所有对应的参数和值对 - 格式为“参数 X”=“abc”,如您在第二张图片中看到的那样,一个接一个地列出。

是否有任何现有的功能可以做到这一点?我真的找不到任何东西。任何帮助将不胜感激。

谢谢。

【问题讨论】:

标签: r list dataframe apriori


【解决方案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",...."=")
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-08
  • 2021-09-28
  • 2019-11-18
  • 2019-05-31
  • 1970-01-01
  • 2019-08-14
  • 1970-01-01
相关资源
最近更新 更多