在现有的names_to列中使用pivot_longer

时间:2020-10-07 16:30:41

标签: r tidyr

以这样一个示例数据框为例(实际数据框具有更多列)

df <- data.frame(A = seq(1, 3, 1),
                 B = seq(4, 6, 1))

我可以像这样使用pivot_longer来收集我感兴趣的列(AB

library(dplyr)
library(tidyr)
df <- df %>% 
  pivot_longer(cols = c("A", "B"), names_to = "Letter", values_to = "Number")
df
  Letter Number
  <chr>   <dbl>
1 A           1
2 B           4
3 A           2
4 B           5
5 A           3
6 B           6

现在让我们说我的数据框中还有另一列C,使其不再整齐

C <- seq(7, 12, 1)

df_2 <- data.frame(df, C)
df_2
  Letter Number  C
1      A      1  7
2      B      4  8
3      A      2  9
4      B      5 10
5      A      3 11
6      B      6 12

我想再次使用pivot_longer使df_2整洁并获得以下输出:

data.frame(Letter = c(rep("A", 3), rep("B", 3), rep("C", 3)),
                        Number = seq(1, 12, 1))
   Letter Number
1       A      1
2       A      2
3       A      3
4       B      4
5       B      5
6       B      6
7       C      7
8       C      8
9       C      9
10      C     10
11      C     11
12      C     12

使用相同的策略会产生错误:

df_2 %>% 
  pivot_longer(cols = "C", names_to = "Letter", values_to = "Number")
Error: Failed to create output due to bad names.
* Choose another strategy with `names_repair`

names_repair设置为minimal会运行,但不会产生我想要的输出。

3 个答案:

答案 0 :(得分:1)

如果有帮助,请尝试以下方法:

library(tidyverse)
#Code
df_2 %>% pivot_longer(everything()) %>%
  arrange(name) %>% group_by(name) %>%
  filter(!duplicated(value))

输出:

# A tibble: 12 x 2
# Groups:   name [3]
   name  value
   <chr> <dbl>
 1 A         1
 2 A         2
 3 A         3
 4 B         4
 5 B         5
 6 B         6
 7 C         7
 8 C         8
 9 C         9
10 C        10
11 C        11
12 C        12

答案 1 :(得分:1)

像这样

@kafka-1-vm:/sys/fs/cgroup/memory/foo$ cat memory.usage_in_bytes
4096

输出

library(tidyverse)
df <- data.frame(A = seq(1, 3, 1),
                 B = seq(4, 6, 1))
df <- df %>% 
  pivot_longer(cols = c("A", "B"), names_to = "Letter", values_to = "Number")

C <- seq(7, 12, 1)
df_2 <- data.frame(C)
df_2 <- df_2 %>% pivot_longer(cols = C, names_to = "Letter", values_to = "Number")

df_result <- rbind(df, df_2)

答案 2 :(得分:0)

我们可以轻松地stack

library(dplyr)
stack(df_2)[2:1] %>% 
     distinct %>%
     set_names(c("Letter", "Number"))

-输出

#    Letter Number
#1       A      1
#2       A      2
#3       A      3
#4       B      4
#5       B      5
#6       B      6
#7       C      7
#8       C      8
#9       C      9
#10      C     10
#11      C     11
#12      C     12

或带有unnest/enframe

的选项
library(tidyr)
library(tibble)
unclass(df_2) %>% 
     enframe(name = "Letter", value = "Number") %>% 
     unnest(c(Number)) %>% 
     distinct

或使用melt

library(reshape2)
melt(df_2) %>% 
      distinct()

或在base R

中一行
unique(stack(df_2)[2:1])