【问题标题】:如果两个字符串在R中的两个不同数据帧中匹配,则分配一个值并求和
【发布时间】:2022-01-23 12:41:56
【问题描述】:

我进行了一项大型调查(由 42 项针对不同治疗的子调查组成),但我无法确定我的数据。

我有大约 16 000 个答案,每个答案(即报纸的替代用途)都是数据框中的一个单元格。这些答案采用数据 1(如下)的形式。

根据一个答案给出的次数,它值 0-6 分(分越多,想的人越少,答案越有创意)。 此列表在形式上与数据 2(如下所列)相同。

现在我想根据数据 2 中的细分对 42 次调查(=参与者)的每一行求和。这个分数应该是数据框中称为“分数”的额外列。

简单示例:

参与者 1 个答案:“schuhe”、“basteln”、... => 分数 = 1 + 0 分 = 1

参与者 2 个答案:“brennmaterial”、“schiff”、... => 分数 = 1 + 1 分 = 2

所以代码应该这样做:

  1. 如果数据 1 的单元格 x 中的字符串(例如“schuhe”)与数据 2 中第 1 列中的字符串匹配(这里:“schuhe”)(总是如此,因为数据 2 是根据数据 1 创建的表),在“points”列的数据2中选择与该匹配字符串对应的值,将其保存在内存中或分配给变量。
  2. 转到行中的下一个单元格,执行步骤 1。
  3. 如果名称为“mycolumns”的所有列都在一行中完成,则将分数相加。
  4. 在数据 1 的“score”列中写入点的总和。
  5. 下一行重复。

数据 1: 42 个调查中的 1 个给出的答案 (sn-p):

structure(list(id = c("1", "2", "3", "4", "7"), kreazeitung_SQ001 = c("fensterglasersatz", 
"dämmmaterial", "klopapier", NA, NA), kreazeitung_SQ002 = c("einwickeln", 
"brennmaterial", "feueranzünder", "putzlappen", "schlagen"), 
    kreazeitung_SQ003 = c("mülleimer", "flieger", "brennmaterial", 
    "brennmaterial", "abdecken"), kreazeitung_SQ004 = c("schuhe", 
    "regenschirm", "basteln", "pappmaschee", "unterlage")), class = "data.frame", row.names = c(NA, 
-5L))

数据 2:以下是每个答案的价值点,例如如果数据1中的答案是“小屋”,则该数据中的“分”列告诉我它值0分,如果是“schuhe”,则应计为1。

structure(list(Var1 = c("basteln", "einwickeln", "abdecken", 
"falten", "schlagen", "feueranzünder", "hut", "unterlage", "collage", 
"fliegenklatsche", "geschenkpapier", "pappmaschee", "zerreißen", 
"brennmaterial", "schiff", "schuhe"), Freq = c(57L, 55L, 46L, 
45L, 43L, 42L, 42L, 42L, 41L, 41L, 41L, 41L, 40L, 39L, 39L, 39L
), points = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1)), row.names = c(9L, 
30L, 1L, 42L, 151L, 47L, 81L, 192L, 20L, 53L, 67L, 126L, 211L, 
16L, 150L, 156L), class = "data.frame")

我对所有解决方案都很满意,无论是 base 还是 tidyverse。 不幸的是,这种代码复杂性超出了我的想象,所以我会很高兴得到任何帮助! 谢谢!

【问题讨论】:

  • 能否请您包括预期的输出。

标签: r dataframe tidyverse reshape tidyr


【解决方案1】:

如果我理解了,那么d2$Var1 中的值与d1 中的所有 Q 列匹配。如果是这样,我认为这会起作用,其中 d1 是数据 1,d2 是数据2

# using data.table package for operations
library(data.table)
d1 <- as.data.table(d1)
d2 <- as.data.table(d2)

# convert from wide format to long
d1_long <- melt(d1, id.vars = "id")
# then can use merge operations to pull the points across
d1_long <- merge(d1_long, d2, by.x="value", by.y="Var1", all.x=TRUE)
# lots of missing values in the e.g., so filled with 0
d1_long[is.na(points), points := 0]

# aggregate the scores, by id
scores <- d1_long[, .(score=sum(points)), by=id]
# add them back in to the original data, sort=FALSE preserves order
d1 <- merge(d1, scores, by="id", sort=FALSE)
d1
   id kreazeitung_SQ001 kreazeitung_SQ002 kreazeitung_SQ003
1:  1 fensterglasersatz        einwickeln         mülleimer
2:  2      dämmmaterial     brennmaterial           flieger
3:  3         klopapier     feueranzünder     brennmaterial
4:  4              <NA>        putzlappen     brennmaterial
5:  7              <NA>          schlagen          abdecken
   kreazeitung_SQ004 score
1:            schuhe     1
2:       regenschirm     1
3:           basteln     1
4:       pappmaschee     1
5:         unterlage     0

# to convert back to data.frame
d1.df <- as.data.frame(d1)

【讨论】:

    猜你喜欢
    • 2018-10-23
    • 1970-01-01
    • 2021-09-10
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 2020-10-10
    相关资源
    最近更新 更多