R语言 特定列中最常见的因素-最近度打破联系

wsxa1bj1  于 2023-04-09  发布在  其他
关注(0)|答案(5)|浏览(112)

我需要在一个数据集中创建一个列,该列在一个列的 * 选择 * 中报告 * 最近的行方式模态**文本值(忽略NA)。
背景:我有一个数据集,最多有4个编码员对参与者的成绩单进行评分(一个参与者/行)。偶尔会有少数编码人员不同意或为参与者/行选择错误的代码。因此,我需要为每个参与者跨编码人员重复选择模态代码响应(即,对于每一行),并且-当存在平局时-选择最近的(稍后的)模态代码响应(因为稍后的编码更可能是正确的)。
这里有一个数据集的假例子,有四个编码器的代码(Essay或Chat),用于3个参与者(一个/行)。

> fakeData = data.frame(id = 1:3,
+                 Condition = c("Essay", "Chat", "Chat"),
+                 FirstCoder = c("NA","Essay","Essay"),
+                 SecondCoder = c("NA","Chat","Essay"),
+                 ThirdCoder = c("Essay","Chat","Chat"),
+                 FourthCoder = c("Essay","NA","Chat"))
> fakeData
  id Condition FirstCoder SecondCoder ThirdCoder FourthCoder
1  1     Essay         NA          NA      Essay       Essay
2  2      Chat      Essay        Chat       Chat          NA
3  3      Chat      Essay       Essay       Chat        Chat

关于最近时间:“FirstCoder”首先编码,“SecondCoder”接着编码,然后“ThirdCoder”提交他们的代码,并且“FourthCoder”是最后(并且最近)提交响应的编码器。
以下是我在其他论坛中尝试过的一些方法-请注意我是如何需要忽略“条件”列的:

> fakeData$ModalCode1 <- apply(fakeData,1,function(x) names(which.max(table(c("FirstCoder","SecondCoder", "ThirdCoder", "FourthCoder")))))
> fakeData$ModalCode2 <- apply(select(fakeData,ends_with("Coder")), 1, Mode)

正确的结果将是此列(手动创建)

> fakeData$MostRecentModalCode <- c("Essay", "Chat", "Chat")

您可以看到我的尝试都没有得到正确的结果(即“MostRecentModalCode”)

> fakeData
  id Condition FirstCoder SecondCoder ThirdCoder FourthCoder ModalCode1 ModalCode2 MostRecentModalCode
1  1     Essay         NA          NA      Essay       Essay FirstCoder         NA               Essay
2  2      Chat      Essay        Chat       Chat          NA FirstCoder       Chat                Chat
3  3      Chat      Essay       Essay       Chat        Chat FirstCoder      Essay                Chat

正如您所看到的,最后一列(正确)忽略了NA,并打破了与最近编码人员响应的模态联系(与传统的Mode函数不同)。

当然有一个函数,但我只是没有找到或正确实现它

欢迎提供建议和解决方案!(如果我必须创建一个自定义函数,那也没问题--尽管令人惊讶。)

0pizxfdo

0pizxfdo1#

我们可以使用here中的Mode函数

> Mode <- function(x) {
+   ux <- unique(x)
+   ux[which.max(tabulate(match(x, ux)))]
+ }
> 
> apply(fakeData[-1], 1, Mode)
[1] "Essay" "Chat"  "Chat"
ecbunoof

ecbunoof2#

@akrun的回答让我看到了另一篇帖子,它有一个自定义的Mode函数,隐藏在符合我需要的答案中。我将其重命名为ModeC,改编自@DanHoughton的答案(https://stackoverflow.com/a/53290748/1701844)中的Mode

ModeC <- function(x) {
  if ( length(x) <= 2 ) return(x[1])
  if ( anyNA(x) ) x = x[!is.na(x)]
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

由于我不明白的原因,它无法忽略fakeData上的NA(无论是data.table还是data.frame,甚至当NA不仅仅是“NA”字符串时),但它在确定我的actualdata中的模式时正确地忽略了NA。所以我在这里发布它,以防它适用于其他人。

m528fe3b

m528fe3b3#

如果您使用data.table,可以尝试以下代码

library(data.table)

melt(setDT(fakeData),
  id.vars = "id", na.rm = TRUE
)[
  , .N,
  .(id, value)
][
  , .(value = value[which.max(N)]),
  id
]

它给出了

id value
1:  1 Essay
2:  2  Chat
3:  3  Chat
wswtfjt7

wswtfjt74#

关于:

apply(fakeData[,-1], 1, DescTools::Mode, na.rm=TRUE)

wsewodh2

wsewodh25#

您可以用途:

apply(fakeData[-1], 1, \(x) names(which(max(table(x))==table(x))))
#[1] "Essay" "Chat"  "Chat"

如果有多个最频繁的级别,它将返回 all

相关问题