首页 > 解决方案 > 对于已经采用“长”格式的数据帧,如何在不转置整个数据帧的情况下将测量变量设为 ID 变量?

问题描述

我正在使用brapi以长格式返回必要数据的包 () 调用数据库。该 api 将某些 ID 变量视为测量变量,这是有问题的,因为我的分析脚本需要它们作为 ID 变量。我不能以这样的方式修改对数据库的调用,它会为我做这件事,我不想只是reshape2::cast然后融化整个事情,因为有数百个变量会使它变得昂贵。理想情况下,我正在寻找一种使用 、 或类似方法来执行此操作的reshape2方法plyr

mtcars使用内置数据框可以看到我的问题。想象一下,您从数据库中获得了长数据框 ,meltedcars其中齿轮作为 ID 变量,但您也希望cyl将其作为 ID 变量。我尝试了明显dcast的命令(例如如下所示),但我知道它不起作用,因为该函数不会cyl作为变量找到。

meltedcars<-melt(mtcars, id.vars = c("gear"))

head(meltedcars)

   gear variable value
1    4      mpg  21.0
2    4      mpg  21.0
3    4      mpg  22.8
4    3      mpg  21.4
5    3      mpg  18.7
6    3      mpg  18.1

c<-dcast(d, gear + cyl ~ variable, value.var= "value")
Error in FUN(X[[i]], ...) : object 'cyl' not found

我已经尝试了上述dcast函数的多次迭代,但无济于事。我已经寻找类似的问题很长一段时间了,但没有找到合适的。我知道我可以用一些 for 循环或重新熔化和铸造来做到这一点,但我想看看是否有更优雅的解决方案。想法?

编辑

我应该更清楚。就本文而言,ID 列是长格式的变量,用于识别正在观察的对象,而不是正在测量的对象。假设我们正在测量数据框中的所有汽车,mpg并且除了数据框中的型号名称作为其自己的列之外,我们还需要有关汽车的其他识别信息。要识别汽车,您有一列汽车名称(我已经调整,以便行名称现在是 mtcars 中的一列,称为),一列它们是什么,一列是多少dispmtcarsmtcarsmodelgearcyl每辆车都有。然后我们有一个变量列和值列,其中分别列出了观察的种类和它的值。当我调用数据库时,这就是我得到的:

头(mtcarsFromDB)

               model gear variable value
1         Mazda RX4    4      mpg  21.0
2     Mazda RX4 Wag    4      mpg  21.0
3        Datsun 710    4      mpg  22.8
4    Hornet 4 Drive    3      mpg  21.4
5 Hornet Sportabout    3      mpg  18.7
6           Valiant    3      mpg  18.1

但是我想用 df 重新格式化这个 df cyl,它当前是一个变量的值,作为一个 ID 列,就像gear没有铸造和熔化整个东西一样。它应该如下所示:

              model gear cyl variable value
1         Mazda RX4    4   6      mpg  21.0
2     Mazda RX4 Wag    4   6      mpg  21.0
3        Datsun 710    4   4      mpg  22.8
4    Hornet 4 Drive    3   6      mpg  21.4 
5 Hornet Sportabout    3   8      mpg  18.7
6           Valiant    3   6      mpg  18.1

标签: rdataframe

解决方案


我将使用您的使用方法复制问题mtcars

df <- head(mtcars) # get a small chunk to work with

df <- df %>% 
  mutate(id = paste0("id", row_number())) # create an id variable

# use tidyr::gather() to "melt" the data:
df_long <- df %>%
  gather()

此时df_long应采用您指示的“问题”格式。

# Here's the problem area. Focus in on the last '10':
df_long %>% tail(10)

    key value
63 carb     1
64 carb     1
65 carb     2
66 carb     1
67   id   id1
68   id   id2
69   id   id3
70   id   id4
71   id   id5
72   id   id6

所以,ids 混在一起了。我假设这是你的问题?以下不是很优雅,但它有效:

# get the id strings, store in `ids`
ids <- df_long %>%
  filter(key == "id") %>%
  select(value) %>%
  .[[1]]

现在,跨行重复 id,最后,删除上面的原始 id 行tail

df_long <- df_long %>%
  mutate(newid = rep(ids, length(unique(.$key)))) %>%
  filter(key != "id") %>%
  select(newid, key, value)

head(df_long)

结果:

  newid key value
1   id1 mpg    21
2   id2 mpg    21
3   id3 mpg  22.8
4   id4 mpg  21.4
5   id5 mpg  18.7
6   id6 mpg  18.1

推荐阅读