如何从 R 中的列进行新的观察?

How can I make new observations from columns in R?

我收到了一个调查数据集,它的结构很奇怪。每行有 90 个变量,前 15 个是一般问题,其他 75 个是 5 组 15 个变量,实际上是观察值。具体案例是雇主被问及雇员的问题。它具有以下结构:

set.seed(42) 
n <- 100
data <- data.frame(
                  EmployerVar1=1:n,,
                  EmployerVar2=rnorm(n),
                  EmployerVar3=rnorm(n),
                  EmployerVar4=rnorm(n),
                  EmployerVar5=rnorm(n),
                  EmployerVar6=rnorm(n),
                  EmployerVar7=rnorm(n),
                  EmployerVar8=rnorm(n),
                  EmployerVar9=rnorm(n),
                  EmployerVar10=rnorm(n),
                  EmployerVar11=rnorm(n),
                  EmployerVar12=rnorm(n),
                  EmployerVar13=rnorm(n),
                  EmployerVar14=rnorm(n),
                  EmployerVar15=rnorm(n),
                  Employee1Var1=rnorm(n),
                  Employee1Var2=rnorm(n),
                  Employee1Var3=rnorm(n),
                  Employee1Var4=rnorm(n),
                  Employee1Var5=rnorm(n),
                  Employee1Var6=rnorm(n),
                  Employee1Var7=rnorm(n),
                  Employee1Var8=rnorm(n),
                  Employee1Var9=rnorm(n),
                  Employee1Var10=rnorm(n),
                  Employee1Var11=rnorm(n),
                  Employee1Var12=rnorm(n),
                  Employee1Var13=rnorm(n),
                  Employee1Var14=rnorm(n),
                  Employee1Var15=rnorm(n),
                  Employee2Var1=rnorm(n),
                  Employee2Var2=rnorm(n),
                  Employee2Var3=rnorm(n),
                  Employee2Var4=rnorm(n),
                  Employee2Var5=rnorm(n),
                  Employee2Var6=rnorm(n),
                  Employee2Var7=rnorm(n),
                  Employee2Var8=rnorm(n),
                  Employee2Var9=rnorm(n),
                  Employee2Var10=rnorm(n),
                  Employee2Var11=rnorm(n),
                  Employee2Var12=rnorm(n),
                  Employee2Var13=rnorm(n),
                  Employee2Var14=rnorm(n),
                  Employee2Var15=rnorm(n),
                  Employee3Var1=rnorm(n),
                  Employee3Var2=rnorm(n),
                  Employee3Var3=rnorm(n),
                  Employee3Var4=rnorm(n),
                  Employee3Var5=rnorm(n),
                  Employee3Var6=rnorm(n),
                  Employee3Var7=rnorm(n),
                  Employee3Var8=rnorm(n),
                  Employee3Var9=rnorm(n),
                  Employee3Var10=rnorm(n),
                  Employee3Var11=rnorm(n),
                  Employee3Var12=rnorm(n),
                  Employee3Var13=rnorm(n),
                  Employee3Var14=rnorm(n),
                  Employee3Var15=rnorm(n),
                  Employee4Var1=rnorm(n),
                  Employee4Var2=rnorm(n),
                  Employee4Var3=rnorm(n),
                  Employee4Var4=rnorm(n),
                  Employee4Var5=rnorm(n),
                  Employee4Var6=rnorm(n),
                  Employee4Var7=rnorm(n),
                  Employee4Var8=rnorm(n),
                  Employee4Var9=rnorm(n),
                  Employee4Var10=rnorm(n),
                  Employee4Var11=rnorm(n),
                  Employee4Var12=rnorm(n),
                  Employee4Var13=rnorm(n),
                  Employee4Var14=rnorm(n),
                  Employee4Var15=rnorm(n),
                  Employee5Var1=rnorm(n),
                  Employee5Var2=rnorm(n),
                  Employee5Var3=rnorm(n),
                  Employee5Var4=rnorm(n),
                  Employee5Var5=rnorm(n),
                  Employee5Var6=rnorm(n),
                  Employee5Var7=rnorm(n),
                  Employee5Var8=rnorm(n),
                  Employee5Var9=rnorm(n),
                  Employee5Var10=rnorm(n),
                  Employee5Var11=rnorm(n),
                  Employee5Var12=rnorm(n),
                  Employee5Var13=rnorm(n),
                  Employee5Var14=rnorm(n),
                  Employee5Var15=rnorm(n))

为了进行分析,数据集需要将每个观察值都放在新的一行中,即雇主特征以及与一名雇员相关联的 15 个变量。所以行数需要增加五倍。

我曾经问过这个问题,虽然我认为这是解决方案,但最终没有奏效。建议是:

library(tidyr)

X_wide <- data.frame(id = 1:3, P1 = 4:6, P2 = 7:9, P3 = 10:12)
X_long <- pivot_longer(X_wide, cols = P1:P3, names_to = "person", values_to = "score")
X_long <- as.data.frame(X_long)

这不起作用,因为它会将所有观察列折叠到一个新变量中。所有的数据都需要保持不变,它只需要降落在一个新的地方。澄清一下,这是我需要分析的结构。

Col1 Col2 Col3 Col4 Col5 Col6
EmployerVar1 EmployerVar2 EmployerVar3 Employee1Var1 Employee1Var2 Employee1Var3
EmployerVar1 EmployerVar2 EmployerVar3 Employee2Var1 Employee2Var2 Employee2Var3
EmployerVar1 EmployerVar2 EmployerVar3 Employee3Var1 Employee3Var2 Employee3Var3

您正在尝试 稍微 更长地重塑数据。

这不是一个简单的 pivot_longer() 因为:

  1. 有些列您不需要重新整形 - 唯一需要重新整形的列从 Employee 开始。您可以使用 starts_with().
  2. 解决此问题
  3. 需要重塑的列包含两部分:第一部分 (Employee) 需要创建新行,但第二部分 (Question) 需要保留在单独的列中。为此,您可以使用 separate() 拆分两部分,并使用 pivot_wider().

为了向您展示一个可能的解决方案,我从头开始重新创建了一个最小可重现数据集

问题可以简化为最小数据集:

  • 两行(一行给雇主)
  • 两列将保持不变
  • 四列需要重塑(每位员工 2 列,每个问题 2 列)

您提供的示例数据与您的实际数据不同:您使用 rnorm() 模拟所有列,但您在评论中说您的数据集实际上主要包含分类数据。这是相关的,因为具有不同的数据类型会使数据透视复杂化。我假设您的数据集仅包含分类或数字列。

我也稍微把Var改成了.Qst,这样我就更清楚他们的意思了,也更容易把员工部分和问题编号部分分开。

library(tidyr)
library(dplyr)

dat <- data.frame(
  EmployerVar1 = c("a", "b"),
  EmployerVar2 = c("d", "e"),
  Employee1.Qst1 = c("A", "B"),
  Employee1.Qst2 = c(1.5, 2.5),
  Employee2.Qst1 = c("F", "G"),
  Employee2.Qst2 = c(-6,-7)
)

dat |> 
  # Change all numerical columns to character
  mutate(across(where(is.double), as.character)) |> 
  # Pivot longer
  pivot_longer(cols = starts_with("Employee"),
               names_to = "Employee.Qst") |>
  # Split 
  separate(col = Employee.Qst, c("Employee", "Question")) |> 
  # Pivot wider
  pivot_wider(names_from = Question, 
              values_from = value)

PS 我真的推荐从 tidyr 开始 the pivoting vignette,这真的很有帮助。