R:有没有一种方法可以将杂乱的数据从长到宽进行排序,当数据在变量之间移动时,排序到一个逻辑键:值列?

R:有没有一种方法可以将杂乱的数据从长到宽进行排序,当数据在变量之间移动时,排序到一个逻辑键:值列?,r,dataframe,dplyr,R,Dataframe,Dplyr,我有非常混乱的数据。它的一部分类似于下面的示例 x1_01=c("bearing_coordinates", "bearing_coordinates", "bearing_coordinates", "roadkill") x1_02=c(146,122,68,1) x2_01=c("tree_density","animals_on_road","animals_

我有非常混乱的数据。它的一部分类似于下面的示例

x1_01=c("bearing_coordinates", "bearing_coordinates", "bearing_coordinates", "roadkill")
x1_02=c(146,122,68,1)
x2_01=c("tree_density","animals_on_road","animals_on_road", "tree_density")
x2_02=c(13,2,5,11)
x3_01=c("animals_on_road", "tree_density", "roadkill", "bearing_coordinates")
x3_02=c(3,10,1,1000)
x4_01=c("roadkill","roadkill", "tree_density", "animals_on_road")
x4_02=c(1,1,12,6)
testframe = data.frame(x1_01 = x1_01,x1_02=x1_02,x2_01=x2_01, x2_02=x2_02, x3_01=x3_01, x3_02=x3_02, x4_01=x4_01, x4_02=x4_02)

            x1_01      x1_02        x2_01    x2_02           x3_01     x3_02           x4_01
1 bearing_coordinates   146    tree_density    13     animals_on_road     3        roadkill
2 bearing_coordinates   122 animals_on_road     2        tree_density    10        roadkill
3 bearing_coordinates    68 animals_on_road     5            roadkill     1    tree_density
4            roadkill     1    tree_density    11 bearing_coordinates  1000 animals_on_road
  x4_02
1     1
2     1
3    12
4     6
我注意到,当使用
dplyr
spread
时,如果我在初始数据表上分散x1_01和x1_02,例如

test <- testframe %>% 
  spread(x1_01, x1_02)
第二个“方位坐标”列将替换原始列,并在有值的情况下生成NAs。为了解决这个问题,我开始创建多个数据帧并将它们合并在一起,例如

  test <- testframe %>% 
  spread(x1_01, x1_02) %>% 
  mutate(id = row_number())
test2 <- testframe %>% 
  spread(x2_01, x2_02)  %>% 
  mutate(id = row_number())
test3 <- testframe %>% 
  spread(x3_01, x3_02)  %>% 
  mutate(id = row_number())
test4 <- testframe %>% 
  spread(x4_01, x4_02)  %>% 
  mutate(id = row_number())

merge_test <- merge(test, test2, by="id")
merge_test2 <- merge(merge_test, test3, by ="id")
merge_test3 <- merge(merge_test2, test4, by = "id")
我想在
dplyr
中一定有一种方法可以非常容易地做到这一点,但我很少有如此混乱的数据,因此我有点不知道什么工具可以实现这一点

我一直在浏览
dplyr
文档等帖子,所有内容似乎都是我想要的,但并不完全正确。例如,这表明可能存在一种不同的策略,即取“beating.coordinates.x”和“beating.coordinates.y”,然后使这些列具有重复的名称,最后合并它们而不丢失数据。然而,这看起来可能更加冗长(特别是对于多个键:值对,就像在我的真实数据集中一样),而且可能会出错。我还认为,
filter
可能是一个不错的选择,但它似乎仍然会遇到列之间相互删除的问题,并导致需要额外的编码步骤来保留所有其余的数据

事先谢谢你的帮助

编辑:Ben下面的回答是正确的,但我最初错误地将变量表示为以“.”分隔,而不是像在我的真实数据中那样以“u”分隔。这可以通过简单地将正则表达式更改为
(.*)或(.*)
来解决,因此:

testframe %>%
  pivot_longer(cols = everything(), names_to = c("name", ".value"), names_pattern = "(.*)_(.*)") %>%
  select(-name) %>%
  pivot_wider(names_from = "01", values_from = "02", values_fn = list) %>%
  unnest(cols = everything())

这是一个非常漂亮和优雅的解决方案。谢谢你,本

也许你可以试试下面这样的东西。根据您的需要,可以对其进行进一步修改,但这在很大程度上取决于您的实际数据。这假设完整的键/值对被平均分割

将首先使用
pivot\u longer
在两列中获取键/值。然后可以使用
pivot\u更宽的
,以便将值放置在相应的键列中

library(tidyr)
library(dplyr)

testframe %>%
  pivot_longer(cols = everything(), names_to = c("name", ".value"), names_pattern = "x(\\d+)_(\\d+)") %>%
  select(-name) %>%
  pivot_wider(names_from = `01`, values_from = `02`, values_fn = list) %>%
  unnest(cols = everything())
输出

  bearing.coordinates tree.density animals.on.road roadkill
                <dbl>        <dbl>           <dbl>    <dbl>
1                 146           13               3        1
2                 122           10               2        1
3                  68           12               5        1
4                1000           11               6        1
bearing.coordinates tree.density animals.on.roadkill
1                 146           13               3        1
2                 122           10               2        1
3                  68           12               5        1
4                1000           11               6        1

也许你可以试试下面这样的方法。根据您的需要,可以对其进行进一步修改,但这在很大程度上取决于您的实际数据。这假设完整的键/值对被平均分割

将首先使用
pivot\u longer
在两列中获取键/值。然后可以使用
pivot\u更宽的
,以便将值放置在相应的键列中

library(tidyr)
library(dplyr)

testframe %>%
  pivot_longer(cols = everything(), names_to = c("name", ".value"), names_pattern = "x(\\d+)_(\\d+)") %>%
  select(-name) %>%
  pivot_wider(names_from = `01`, values_from = `02`, values_fn = list) %>%
  unnest(cols = everything())
输出

  bearing.coordinates tree.density animals.on.road roadkill
                <dbl>        <dbl>           <dbl>    <dbl>
1                 146           13               3        1
2                 122           10               2        1
3                  68           12               5        1
4                1000           11               6        1
bearing.coordinates tree.density animals.on.roadkill
1                 146           13               3        1
2                 122           10               2        1
3                  68           12               5        1
4                1000           11               6        1

您能否根据示例数据澄清最终/所需数据框的外观?如果你不介意的话,你能编辑你的问题并加上这个吗?@Ben,我很抱歉没有从一开始就加上这个!我已经做了编辑。你能根据你的示例数据澄清你最终/想要的数据框架应该是什么样子吗?如果你不介意的话,你能编辑你的问题并加上这个吗?@Ben,我很抱歉没有从一开始就加上这个!我已经做了编辑。我应该看看新的文档!我不知道pivot有这种能力(与spread and gather的功能相比)。这段代码看起来很完美,但我已经意识到正则表达式是不正确的,因为我的变量之间用下划线而不是句点分隔。我为这个错误感到抱歉-我将在帖子中进行编辑。我应该看看新的文档!我不知道pivot有这种能力(与spread and gather的功能相比)。这段代码看起来很完美,但我已经意识到正则表达式是不正确的,因为我的变量之间用下划线而不是句点分隔。我为这个错误感到抱歉-我将在帖子中进行编辑。