【问题标题】:Split columns into adjacent columns, use row name as new column name in R将列拆分为相邻列,使用行名作为 R 中的新列名
【发布时间】:2016-04-18 21:27:33
【问题描述】:

我有一个数据框,其中包含两列识别信息和一列由连字符分隔的字母对:

df<-data.frame(
    list = rep(1:3, each = 2),
    set =  rep(c("A","B"), times = 3),
    item = c("ab-cd","ef-gh","ij-kl","mn-op","qr-st","uv-wx")  
    )

我一直在努力完成的是将数据框转换为以下形式,其中: 1. 由“list”索引的单独行分别折叠成一行; 2.“item”列以连字符为分隔符分割成相邻的列; 3. "set" 列作为命名结果列的基础。

df2 <- data.frame(
       list = c(1:3),
       A_1 = c("ab", "ij", "qr"),
       A_2 = c("cd", "kl", "st"),
       B_1 = c("ef", "mn", "uv"), 
       B_2 = c("gh", "op", "wx"))

我参考了一些之前发布的问题(特别是 [这里])并尝试使用 BASE 转置函数以及各种绑定函数以及 reshape 包和splitstackshape 包。我的近乎解决方案都不是优雅的,我想知道是否有这样做的好方法。

与往常一样,我非常感谢社区提供的建议和反馈。

【问题讨论】:

  • 你能展示一些你的解决方案吗?你可能就快到了!
  • 您需要 dplyr/tidy 包来完成图片 - dplyr 中的 group_by() 和 tidyr 中的 spread() 应该会有所帮助。

标签: r split transformation


【解决方案1】:

非常感谢@AnandaMahto:它可以通过首先重塑然后拆分而不是相反的方式在一行中完成。

library(splitstackshape)
cSplit(dcast(as.data.table(df), list ~ set, value.var = "item"), c("A", "B"), "-")

我们可以使用 base R 和 reshape2 分两步完成。

首先,我们创建包含拆分项的列“1”和“2”。通常情况下,我们不会使用数字字符来作为列名的开头,但这样可以省去我们稍后重命名结果列的步骤。

df[,c("1","2")] <- do.call(rbind,strsplit(as.character(df$item),"-"))

然后我们使用recast:

res <- recast(data=df, list~set+variable, measure.var=c("1","2"))
res

  list A_1 A_2 B_1 B_2
1    1  ab  cd  ef  gh
2    2  ij  kl  mn  op
3    3  qr  st  uv  wx

【讨论】:

  • 抱歉,我无法及时发布我失败的解决方案示例,但这是一个有用的回复。非常感谢@Heroka
  • 我会做cSplit(dcast(as.data.table(df), list ~ set, value.var = "item"), c("A", "B"), "-")....
  • @AnandaMahto 非常感谢!我已将其添加到答案中,希望您没问题(并删除了我的两步 splitstackshape-solution)。
  • 没问题。很高兴能帮忙:-)
  • @AnandaMahto 和 Herka...你们是我今天需要的梦之队!非常感谢!
【解决方案2】:

为了完整起见,这在 Hadleyverse 中也很有效:

library(dplyr)
library(tidyr)
df %>% 
  separate(item, 1:2) %>% 
  gather(val, item, -set, -list) %>% 
  mutate(set=paste(set, val, sep="_")) %>% 
  select(-val) %>% 
  spread(set, item)
#   list A_1 A_2 B_1 B_2
# 1    1  ab  cd  ef  gh
# 2    2  ij  kl  mn  op
# 3    3  qr  st  uv  wx

【讨论】:

    【解决方案3】:

    为了完整起见,这也可以很好地与 Hadleyverse 的基本 R 克星reshape

    reshape(cbind(df[-3], 
                  do.call(rbind, strsplit(as.character(df$item), "-"))), 
            direction = "wide", idvar = "list", timevar = "set")
    #   list 1.A 2.A 1.B 2.B
    # 1    1  ab  cd  ef  gh
    # 3    2  ij  kl  mn  op
    # 5    3  qr  st  uv  wx
    

    (但是dcast + cSplit 会更有效率和可读性)。

    【讨论】:

      猜你喜欢
      • 2015-01-13
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多