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的功能相比)。这段代码看起来很完美,但我已经意识到正则表达式是不正确的,因为我的变量之间用下划线而不是句点分隔。我为这个错误感到抱歉-我将在帖子中进行编辑。