【发布时间】:2021-01-21 16:19:10
【问题描述】:
我手头有一个多级数据集df,隶属于以下组织:
ID Eye Video_number Time Day measurement1
40001 L 1 1 1 0.60
40001 L 2 1 1 0.50
40001 L 3 1 1 0.80
40001 L 1 2 1 0.60
40001 L 2 2 1 0.60
40001 L 3 2 1 0.60
目标我正在尝试用NA 替换方差系数大于 45 的测量值的单元格值,因为这些值可能不太精确,应该被排除在外。
分布的变异系数(有时表示为 CV)定义为标准差与平均值的比率,其中 $\mu$ 和 $\sigma$ 值从原始数据中获得
- 我使用以下函数和 for 循环按时间单位(一个时间单位中三个视频的平均测量值)获得了 CV 值。我从以下主题中获得了帮助:
How to correctly use group_by() and summarise() in a For loop in R
Append data frames together in a for loop
# Define function
cv <- function(x){
sd(na.omit(x))/mean(na.omit(x))*100}
# Variables
vars <- c("measurement1", "measurement2", "measurement3")
# Create a table with all CV values by ID, Eye, Day, and Time
df_cv=data.frame()
for (i in vars){
df<-df.m2
df$values<-df[,which(colnames(df.m2)==i)]
x<-df%>%
group_by(ID,Eye,Day,Time) %>%
summarise(Count = n(),
Mean = mean(values, na.rm = TRUE),
SD = sd(values, na.rm = TRUE),
CV = cv(values))%>%
mutate(Variable=paste(i,"cv",sep="_"))
df_cv<-rbind(df_cv,x)
df_cv$CV[is.nan(df_cv$CV)]<-0 # for 0/0 on CV formula giving NaN
}
- 结果如下表
df_cv:
ID Eye Day Time Count Mean SD CV Variable
40001 L 1 1 3 0.56666667 0.057735027 10.1885342 measurement1_cv
40001 L 1 2 3 0.36666667 0.404145188 110.2214150 measurement1_cv
40001 L 1 3 3 0.50000000 0.000000000 0.0000000 measurement1_cv
- 我将上面的
df_cv重新格式化为宽格式(变量和 CV 跨行而不是列)。这使我能够将 CV 与原始df合并
df_cv<-dcast(df_cv,PIDN+Eye+Day+Time~Variable,value.var = "CV")
df<-merge(df,df_cv,by=c("PIDN","Eye","Day","Time"))
ID Eye Video_number Time Day measurement1 measurement1_cv
40001 L 1 1 1 0.60 10.1885342
40001 L 2 1 1 0.50 10.1885342
40001 L 3 1 1 0.80 10.1885342
40001 L 1 2 1 0.80 110.2214150
40001 L 2 2 1 0.30 110.2214150
40001 L 3 2 1 0.00 110.2214150
- 我知道想将 NA 输入到 CV>45 的测量 1 的单元格中。我知道如何通过测量来进行测量,但我想知道是否有一个 for 循环能够做到这一点,因为我要分析很多变量。
df$measurement1[df$measurement1_cv>45]<-NA
df$measurement2[df$measurement2_cv>45]<-NA
df$measurement3[df$measurement3_cv>45]<-NA
以下是我失败的尝试:
for (i in vars) {
df<-df.m3
df$i[df$i_cv>45]<-NA
}
Error in `$<-.data.frame`(`*tmp*`, "i", value = logical(0)) :
replacement has 0 rows, data has 609
for (i in vars) {
df<-df.m3
df$i[df$paste(i,"_cv")>45]<-NA
}
Error in df$paste(i, "_cv") : attempt to apply non-function
非常感谢任何帮助!
【问题讨论】:
-
df[,c(2,4,17,23)] <- lapply(df[,c(2,4,17,23)], function(a) replace(a, a > 45, NA))这里的数字向量是您需要的列。也可以是逻辑向量,可能来源于startsWith(colnames(df), "measurement") -
谢谢!但是,我需要按 Time 实例应用 CV 公式,这就是我使用
group_by(ID,Eye,Day,Time)的原因我尝试了以下操作:lapply(df[,vars], function(cv) replace(cv,cv>45,NA))并且我认为它不能识别时间单位,通过它来采取手段和 sd视频。它用NA替换了许多值。