【问题标题】:Filter for two-part response data from another dataframe and join two dataframes过滤来自另一个数据帧的两部分响应数据并连接两个数据帧
【发布时间】:2018-10-19 19:45:57
【问题描述】:

我有一个调查问题,格式为:“你喜欢玫瑰还是郁金香?想象玫瑰有 V1 和 V2 的颜色,而郁金香有 V3 和 V4 的颜色”

实际颜色来自一个数据帧中包含的组合:

数据帧 1 (df1):

structure(list(V1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("red", "ruby"), class = "factor"), 
V2 = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L,
1L, 1L, 2L, 2L, 2L, 2L), .Label = c("blue", "violet"), class = "factor"), 
V3 = structure(c(1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 
2L, 2L, 1L, 1L, 2L, 2L), .Label = c("green", "turqoise"), class = "factor"), 
V4 = structure(c(2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 
2L, 1L, 2L, 1L, 2L, 1L), .Label = c("black", "yellow"), class = "factor")), .Names = c("V1", 
"V2", "V3", "V4"), class = "data.frame", row.names = c(NA, -16L
))

在此数据帧 (df1) 中,前两列(V1 和 V2)对应于“玫瑰”,最后两列(V3 和 V4)对应于“郁金香”。例如,可以向受访者显示 df1 第一行的组合 1,即“红蓝绿黄”。这意味着受访者可以选择“红色和蓝色的玫瑰”或“绿色和黄色的郁金香”。

受访者做出的选择包含在单独的数据框 (df2) 中。 df2 每个颜色组合都有一列。如果受访者 1 看到 df1 中的第一个组合(“红蓝绿黄”)并选择了一个郁金香(即绿色和黄色),则选择在第一行标记为“2”(郁金香,即第二朵花) df2。如果受访者 2 看到了 df1 中的第二个组合(“红蓝绿黑”)并选择了一朵玫瑰(即红色和蓝色),则选择在第二行标记为“1”(代表玫瑰,即第一朵花) df2。换句话说,“2”表示“选择了郁金香,没有选择了玫瑰”,而“1”表示了“选择了玫瑰,没有选择了郁金香”。

数据框 2 (df2):

structure(list(respondentID = 1:16, v1 = c(2L, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), v2 = c(NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), v3 = c(NA, 
NA, NA, NA, NA, NA, 1L, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
    v4 = c(NA, NA, NA, 2L, NA, NA, NA, NA, NA, NA, 1L, 2L, NA, 
    NA, NA, NA), v5 = c(NA, NA, 1L, NA, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA, NA), v6 = c(NA, 2L, NA, NA, NA, NA, NA,
    NA, NA, 1L, NA, NA, NA, NA, NA, NA), v7 = c(NA, NA, NA, NA, 
    1L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), v8 = c(NA, 
    NA, NA, NA, NA, 1L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA
    ), v9 = c(NA, NA, NA, NA, NA, NA, NA, 2L, NA, NA, NA, NA, 
    NA, NA, NA, NA), v10 = c(NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA), v11 = c(NA, NA, NA, NA, 
    NA, NA, NA, NA, 1L, NA, NA, NA, NA, NA, NA, NA), v12 = c(NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1L, NA, NA, NA
    ), v13 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, 1L, NA, NA), v14 = c(NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA), v15 = c(NA, NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), v16 = c(NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 2L
    )), .Names = c("respondentID", "v1", "v2", "v3", "v4", "v5",
"v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", 
"v16"), class = "data.frame", row.names = c(NA, -16L))

如果我只想知道选择了哪种花和颜色,我可以使用:

df1_with_id <- df1 %>% 
  setNames(paste0("color", 1:4)) %>%
  mutate(combo = paste0("v", row_number()))

result_df <- df2 %>%
  gather(key = combo, value = val, -respondentID) %>%
  filter(!is.na(val)) %>%
  left_join(df1_with_id, by = "combo") %>%
  arrange(respondentID)

(As per this question)

但这并没有给我我需要的格式。我需要在单独的行中显示给每个受访者的两个选项(即“玫瑰是 V1 和 V2”和“郁金香是 V3 和 V4”)的信息,以及一个指示两个选项之间选择的附加变量,如下所示: Desired result

(图中choice变量中的“1”表示被访者选择的选项,“0”表示未选择的选项。)

我不太清楚如何编写代码以这种方式组织数据。有什么建议吗?

【问题讨论】:

  • 我意识到我根本没有很好地解释这个问题。我现在已经修好了。
  • Flower 就是 rosetulip。如果 flower 列中的单元格是 rose,则 color1color2 包含有关 color1 的颜色信息i>玫瑰。 tulip 的颜色在下面的行中。没有受访者做出两种选择;每个受访者都会看到两个选项(rose 有两种颜色,tulip 有两种颜色)并选择其中一个选项。 choice 是指所做的选择。如果 choice = 1,则选择该行中的花;如果choice = 0,则该行中的花未被受访者选择。
  • responsiveID = 2 中的额外值是一个错字。对不起。现在修好了。 respondentID= 9 只有一个响应(除非我遗漏了什么)。但无论如何:每个受访者只能做出一个选择。另一个问题正是诀窍:在 df1 中,我们将 V1、V2、V3 和 V4 全部放在一行中。在 result_df 中,我需要 V1 和 V2 在一行中(rose 旁边),V3 和 V4 在下面的行中(tulip 旁边)——以及一列指示选择了哪一朵花。

标签: r dataframe tidyr data-cleaning


【解决方案1】:

这里的主要问题是df1 中的每一列都表示两种信息:花型和颜色编号。所以重命名它们以包含这两个信息,将它们收集到一列中,将键列分成flowercolor 列,然后展开color 列。然后你只需要将val 转换为1,如果它匹配flower 列,否则0

df2 %>%
  gather(key = combo, value = val, -respondentID) %>%
  filter(!is.na(val)) %>%
  left_join(df1_with_id, by = "combo") %>%
  arrange(respondentID) %>% 
  rename(rose_color1 = color1, rose_color2 = color2,
         tulip_color1 = color3, tulip_color2 = color4) %>% 
  gather(color, value, rose_color1:tulip_color2) %>% 
  separate(color, into = c('flower', 'color')) %>% 
  spread(color, value) %>% 
  mutate(val = if_else(val == 1, 'rose', 'tulip')) %>% 
  mutate(val = if_else(val == flower, 1, 0)) %>% 
  select(respondentID, flower, color1, color2, choice = val)

【讨论】:

  • 这行得通。谢谢你。只是一个小小的修正。应该是mutate(val = if_else(val == flower, 0, 1)) %&gt;% ,而不是mutate(val = if_else(val == flower, 1, 0)) %&gt;%
  • 根据您帖子中的评论,我认为情况并非如此,但这是一个较小的解释问题,对实际问题并不那么重要......选择变量中的“1”是指到受访者选择的选项
  • 实际上,我明白你为什么这么认为....前面的行实际上是不正确的...应该是mutate(val = if_else(val == 1, 'rose', 'tulip')) %&gt;% ...我将修复/编辑我的示例。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
  • 2018-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多