【问题标题】:R : Add dynamic column name to row in R [duplicate]R:将动态列名添加到R中的行[重复]
【发布时间】:2016-12-13 10:00:18
【问题描述】:

样本数据:

df <- data.frame(ProdCode = c("C1","C2"), ProdName = c("Product 1", "Product 2"), Category = c("Categ 1", "Categ 2"), "Jan-16" = c(3,2), "Apr-16" = c(3,""), "Jul-16" = c(5,2), "Oct-16" = c(5,2))

每个月对应的值和产品单元格是该产品的评级。这需要在输出数据框中的评级列中:

> df
  ProdCode  ProdName Category Jan.16 Apr.16 Jul.16 Oct.16
1       C1 Product 1  Categ 1      3      3      5      5
2       C2 Product 2  Categ 2      2             2      2

我有以下格式所需的以上数据:

ProdCode  Product.Name  Category    Rating.Date   Rating
C1          Product 1   Categ 1     Jan-16         3
C1          Product 1   Categ 1     Apr-16         3
C1          Product 1   Categ 1     Jul-16         5
C1          Product 1   Categ 1     Oct-16         5
C2          Product 2   Categ 2     Jan-16         2
C2          Product 2   Categ 2     Jul-16         2
C2          Product 2   Categ 2     Oct-16         2

月份列是动态的,并且会增加,例如将来根据产品将在 2017 年 1 月出现等。我可以通过使用 for 循环来做到这一点,但不值得使用 R。

【问题讨论】:

  • 查看reshape2 包,特别是melt() 函数
  • 检查 tidyr::gather
  • @mpjdem,是的,melt() 可以工作,谢谢

标签: r data.table dplyr


【解决方案1】:

这些是我们拥有的其他不同选项:

注意:您可以随意命名最后两列,我将其保留为默认值(变量和值)

使用melt() from data.frame

library(reshape2)
df1 = melt(df, id.vars = c("ProdCode" , "ProdName" ,"Category"), measure.vars = 4:7)
df1 = df1[df1$value != "",]

使用melt from data.table)

library(data.table)
setDT(df) 
melt.data.table(df, 1:3,4:7)[value!=""]  # '1:3, 4:7' are the column indexes. read more from ?melt

#  ProdCode  ProdName Category variable value
#1       C1 Product 1  Categ 1   Jan.16     3
#2       C2 Product 2  Categ 2   Jan.16     2
#3       C1 Product 1  Categ 1   Apr.16     3
#5       C1 Product 1  Categ 1   Jul.16     5
#6       C2 Product 2  Categ 2   Jul.16     2
#7       C1 Product 1  Categ 1   Oct.16     5
#8       C2 Product 2  Categ 2   Oct.16     2

# if you want your specific column names :

melt.data.table(df, 1:3,4:7, variable.name = "Rating.Date", value.name = "Rating")[Rating!=""]
#   ProdCode  ProdName Category Rating.Date Rating
#1:       C1 Product 1  Categ 1      Jan.16      3
#2:       C2 Product 2  Categ 2      Jan.16      2
#3:       C1 Product 1  Categ 1      Apr.16      3
#4:       C1 Product 1  Categ 1      Jul.16      5
#5:       C2 Product 2  Categ 2      Jul.16      2
#6:       C1 Product 1  Categ 1      Oct.16      5
#7:       C2 Product 2  Categ 2      Oct.16      2

【讨论】:

  • 只需使用melt() - 如果你给它一个data.table,它会在后台调用melt.data.table
  • @DavidArenburg 代码更简洁,在我的观察中更快
  • 感谢您的评论。 @DavidArenburg 我需要弄清事实..
【解决方案2】:

我们可以使用gather 将其重塑为'long',filter 将'Rating' 中的空白和arrange 'ProdCode' 中的空白

library(tidyr)
library(dplyr)
gather(df, Rating.Date, Rating, Jan.16:Oct.16) %>%
            filter(Rating !="") %>%
            arrange(ProdCode) 
#  ProdCode  ProdName Category Rating.Date Rating
#1       C1 Product 1  Categ 1      Jan.16      3
#2       C1 Product 1  Categ 1      Apr.16      3
#3       C1 Product 1  Categ 1      Jul.16      5
#4       C1 Product 1  Categ 1      Oct.16      5
#5       C2 Product 2  Categ 2      Jan.16      2
#6       C2 Product 2  Categ 2      Jul.16      2
#7       C2 Product 2  Categ 2      Oct.16      2

【讨论】:

  • df @akrun 中没有 rating 和 rating.date
  • @user_az 这是我们提供的要在输出中创建的键和值名称
猜你喜欢
  • 1970-01-01
  • 2021-12-01
  • 2017-12-04
  • 1970-01-01
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
  • 2016-06-07
  • 2017-04-11
相关资源
最近更新 更多