我有一个包含超过 14000 个观察值和 43 个变量的数据集。数据是在 11 个国家/地区收集的,对于其中两个问题,参与者根据他们所在的国家/地区被问及同一问题的不同变体,这意味着对于 2 个变量,我实际上有 22 列。基本上,这是一个 df 的例子:
df <- data-frame(country = c(1, 1, 1, 2, 2, 2, 3, 3, 3), Q1_UK = c(1, 2, 2, NA, NA, NA, NA, NA, NA), Q1_FR = c(NA, NA, NA, 2, 1, 2, NA, NA, NA), Q1_ES = c(NA, NA, NA, NA, NA, NA, 2, 2, 1), Q2_UK = c(1, 1, 2, NA, NA, NA, NA, NA, NA), Q2_FR = c(NA, NA, NA, 1, 2, 2, NA, NA, NA), Q2_ES = c(NA, NA, NA, NA, NA, NA, 1, 2, 1))
country Q1_UK Q1_FR Q1_ES Q2_UK Q2_FR Q2_ES
1 1 1 NA NA 1 NA NA
2 1 2 NA NA 1 NA NA
3 1 2 NA NA 2 NA NA
4 2 NA 2 NA NA 1 NA
5 2 NA 1 NA NA 2 NA
6 2 NA 2 NA NA 2 NA
7 3 NA NA 2 NA NA 1
8 3 NA NA 2 NA NA 2
9 3 NA NA 1 NA NA 1
等等……
我想要 2 个单一变量,其中包含针对不同国家/地区的所有响应 - 最终结果如下:
country Q1 Q2
1 1 1 1
2 1 2 1
3 1 2 2
4 2 2 1
5 2 1 2
6 2 2 2
7 3 2 1
8 3 2 2
9 3 1 1
我在想旋转数据框,使用 fill(),然后再次旋转可能会起作用,但我不太确定如何去做以及如何确保答案只按问题而不是跨变量填写。我真的是 R 的新手,我已经筋疲力尽了,所以我可能只是遗漏了一些明显的东西。
这可以用
pivot_longer
来完成
library(tidyr)
pivot_longer(df, cols = -country, names_to = c(".value"),
names_pattern = "(.*)_.*", values_drop_na = TRUE)
-输出
A tibble: 9 × 3
country Q1 Q2
<int> <int> <int>
1 1 1 1
2 1 2 1
3 1 2 2
4 2 2 1
5 2 1 2
6 2 2 2
7 3 2 1
8 3 2 2
9 3 1 1
1。方法
library(dplyr)
library(tidyr)
df %>%
unite(newcol, -country, na.rm = TRUE) %>%
separate(newcol, into = LETTERS[1:ncol(df)]) %>%
select(where(function(x) any(!is.na(x))))
country A B
1 1 1 1
2 1 2 1
3 1 2 2
4 2 2 1
5 2 1 2
6 2 2 2
7 3 2 1
8 3 2 2
9 3 1 1
Warning message:
Expected 7 pieces. Missing pieces filled with
`NA` in 9 rows [1, 2, 3, 4, 5, 6, 7, 8, 9].
2。方法
这是一个使用
names_sep
修改的。如果我们使用names_sep
,我们必须将列名添加到names_to
,因为names_sep
不能与a一起使用
长度 1 names_to
:
library(tidyr)
library(dplyr)
pivot_longer(df, cols = -country,
names_to = c(".value", "name"),
names_sep = "_",
values_drop_na = TRUE)
country name Q1 Q2
<dbl> <chr> <dbl> <dbl>
1 1 UK 1 1
2 1 UK 2 1
3 1 UK 2 2
4 2 FR 2 1
5 2 FR 1 2
6 2 FR 2 2
7 3 ES 2 1
8 3 ES 2 2
9 3 ES 1 1