【问题标题】:reshaping data frame r重塑数据帧 r
【发布时间】:2015-02-03 20:48:00
【问题描述】:

简单整形,我有以下数据:

df<-data.frame(Product=c("A","A","A","B","B","C"), Ingredients=c("Chocolate","Vanilla","Berry","Chocolate","Berry2","Vanilla"))
df
Product Ingredients
1   A   Chocolate 
2   A     Vanilla
3   A       Berry
4   B   Chocolate
5   B      Berry2
6   C     Vanilla

我想为“成分”的每个唯一值设置一列,例如:

df2
Product Ingredient_1 Ingredient_2 Ingredient_3
A       Chocolate       Vanilla        Berry
B       Chocolate       Berry2         NULL
C       Vanilla         NULL           NULL

似乎微不足道,我尝试重塑但我不断得到计数(不是“成分”的实际值)。想法?

【问题讨论】:

  • 显示您尝试过但不起作用的代码。您基本上是将数据从“长”格式重塑为“宽”格式。关于这个话题已经有很多很多问题了。您确定在发布新问题之前彻底搜索了现有答案吗?
  • 我试过:dcast(df, Product ~ Ingredients, value.var = "Ingredients"),但它为每个产品创建了一个列
  • @MrFlick 这个问题有什么不清楚的地方? OP 说他们尝试了reshape,但没有成功。并且很清楚为什么-因为这不是一个简单的重塑问题。如果你能找到一个骗子,请关闭问题。如果没有,为什么 OP 能够做到?
  • @DavidArenburg 主要是因为“我尝试重塑”非常不清楚。如果您遇到代码问题,请显示您尝试过的代码并给出确切的错误。从上面的评论来看,他们似乎没有使用reshape(),而是使用reshape(可能是reshape2)库。

标签: r dataframe reshape


【解决方案1】:

这是使用data.table 包的可能解决方案

library(data.table)
setDT(df)[, Ingredient := paste0("Ingredient_", seq_len(.N)), Product]
dcast(df, Product ~ Ingredient, value.var = "Ingredients")
#    Product Ingredient_1 Ingredient_2 Ingredient_3
# 1:       A    Chocolate      Vanilla        Berry
# 2:       B    Chocolate       Berry2           NA
# 3:       C      Vanilla           NA           NA

另外,我们可以使用性感的dplyr/tidyr 组合来做到这一点

library(dplyr)
library(tidyr)
df %>% 
  group_by(Product) %>%
  mutate(Ingredient = paste0("Ingredient_", row_number())) %>%
  spread(Ingredient, Ingredients)

# Source: local data frame [3 x 4]
# 
#   Product Ingredient_1 Ingredient_2 Ingredient_3
# 1       A    Chocolate      Vanilla        Berry
# 2       B    Chocolate       Berry2           NA
# 3       C      Vanilla           NA           NA

【讨论】:

    【解决方案2】:

    本着分享替代方案的精神,这里还有两个:

    选项 1split 列并使用 stri_list2matrix 创建宽表单。

    library(stringi)
    x <- with(df, split(Ingredients, Product))
    data.frame(Product = names(x), stri_list2matrix(x))
    #   Product        X1        X2      X3
    # 1       A Chocolate Chocolate Vanilla
    # 2       B   Vanilla    Berry2    <NA>
    # 3       C     Berry      <NA>    <NA> 
    

    选项 2:使用我的“splitstackshape”包中的getanID 生成一个“.id”列,然后使用dcast 它。 “data.table”包中加载了“splitstackshape”,可以直接调用dcast.data.table进行整形。

    library(splitstackshape)
    dcast.data.table(getanID(df, "Product"), 
                     Product ~ .id, value.var = "Ingredients")
    #    Product         1       2     3
    # 1:       A Chocolate Vanilla Berry
    # 2:       B Chocolate  Berry2    NA
    # 3:       C   Vanilla      NA    NA
    

    【讨论】:

      【解决方案3】:

      带基 R reshape

      df$Count<-ave(rep(1,nrow(df)),df$Product,FUN=cumsum)
      reshape(df,idvar="Product",timevar="Count",direction="wide",sep="_")
      
      #  Product Ingredients_1 Ingredients_2 Ingredients_3
      #1       A     Chocolate       Vanilla         Berry
      #4       B     Chocolate        Berry2          <NA>
      #6       C       Vanilla          <NA>          <NA>
      

      【讨论】:

      • 您可能还对我的“splitstackshape”包中的getanID 感兴趣。它会创建一个名为".id" 的列作为“计数”,因此您可以这样做:reshape(getanID(df, "Product"), direction = "wide", idvar = "Product", timevar = ".id")。 +1
      猜你喜欢
      • 2011-12-22
      • 2012-10-15
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2014-03-10
      • 2017-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多