dplyr:在group_by之后用零替换NAs,同时将原始NAs保留在R中
我正在创建一个新变量,因为NAs,并且因为只有一些人符合分组标准,我最终的数据集中有许多新的NAs 这是数据 更新的示例数据帧:dplyr:在group_by之后用零替换NAs,同时将原始NAs保留在R中,r,dplyr,group-by,mutate,R,Dplyr,Group By,Mutate,我正在创建一个新变量,因为NAs,并且因为只有一些人符合分组标准,我最终的数据集中有许多新的NAs 这是数据 更新的示例数据帧: id age year var1 4 KL 2007 15 1 KL 2008 10 2 KL 2008 20 4 AG 2008 NA 3 AG 2008 5 3 SU 2009 NA 4 SU
id age year var1
4 KL 2007 15
1 KL 2008 10
2 KL 2008 20
4 AG 2008 NA
3 AG 2008 5
3 SU 2009 NA
4 SU 2009 NA
4 LL 2011 NA
数据帧细微差别:
age==“KL”&year==2007
只有一行(带值)age==“KL”&year==2008
有多行(带值)age==“AG”&year==2008
有多行(带值和NAs)age==“SU”&year==2009
有多行(仅限NAs)age==“LL”&year==2011
只有一行(带NA)df<-df %>%
group_by(age, year) %>%
mutate(new_var1=((var1-mean(var1, na.rm=T))/(1*(sd(var1, na.rm=T)))))
期望输出:
id age year var1 new_var1
4 KL 2007 15 0
1 KL 2008 10 -0.7071068
2 KL 2008 20 0.7071068
4 AG 2008 NA NA
3 AG 2008 5 0
3 SU 2009 NA NA
4 SU 2009 NA NA
4 LL 2011 NA NA
在强制任何新NAs实例(因为行是唯一的记录)为0而不是NA时,如何保留现有NAs(这些是丢失数据的真实实例)?
非常感谢dplyr
解决方案
我知道如何用零替换NAs(例如,
mutate(new_var1=ifelse(is.na(new_var1),0,new_var1))
),但这将替换所有NAs,而不仅仅是新NAs。我们可以使用if/else
创建一个条件来检查单个观测值,如果它不是na,则返回0或执行计算
library(dplyr)
df %>%
group_by(age, year) %>%
mutate(var1 = if(n() == 1 && !is.na(var1) | sum(!is.na(var1)) == 1) 0 * var1
else ((var1-mean(var1, na.rm=TRUE))/(1*(sd(var1, na.rm=TRUE))))) %>%
ungroup
-输出
# A tibble: 8 x 4
id age year var1
<int> <chr> <int> <dbl>
1 4 KL 2007 0
2 1 KL 2008 -0.707
3 2 KL 2008 0.707
4 4 AG 2008 NA
5 3 AG 2008 0
6 3 SU 2009 NA
7 4 SU 2009 NA
8 4 LL 2011 NA
#一个tible:8 x 4
id年龄年变量1
14吉隆坡2007 0
21吉隆坡2008-0.707
3.2吉隆坡2008 0.707
4 4 AG 2008 NA
5 3 AG 2008 0
6 3苏2009 NA
7 4苏2009 NA
2011年4月8日北美
数据
df选项可以是:
df%
按年龄、年份划分的组别%>%
变异(new_var1=ifelse(is.nan(scale(var1)),0,scale(var1)))%>%
解组()
#>#A tibble:8 x 5
#>id年龄年变量1新变量1[,1]
#>
#>14吉隆坡2007 15 0
#>2 1吉隆坡2008 10-0.707
#>3 2吉隆坡2008 20 0.707
#>4 4 AG 2008 NA
#>5 3 AG 2008 5 0
#>6 3苏2009娜娜娜
#>7 4苏2009纳纳
#>2011年4月8日不适用
库(数据表)
setDT(df)[,new_var1:=ifelse(is.nan(scale(var1)),0,scale(var1)),by=list(age,year)][]
#>id年龄年变量1新变量1
#>1:4 KL 2007 150.0000000
#>2:1吉隆坡2008 10-0.7071068
#>3:2吉隆坡2008 20 0.7071068
#>4:4 AG 2008 NA NA
#>5:3 AG 2008 500.0000000
#>6:3苏2009娜娜娜
#>7:4苏2009娜娜娜
#>8:4 LL 2011不适用
由(v2.0.0)于2021-05-21创建。由于某种原因,当我尝试应用您的解决方案时,它会为整个列返回NaN。你能帮我解决一下为什么它对你的答案有效,但对我来说不行吗?@BlunderingColomist这是基于你展示的同一个例子吗?在您的原始数据中,我猜测有多个组有一个以上的观察,并且所有组都是NA,这导致NaN
,而您使用mean
进行计算,啊,我认为可能是这样。我试图用上面一个简明的例子来避免让它压倒一切,但我认为我遗漏了一些重要的细微差别?@BlunderingColomist我在这里没有包括这个条件。此外,在某些情况下,有一个单独的非NA元素,sd可以返回NAI think,这在我的原始数据集中更为常见(一个单独的非NA元素,由于sd()
函数,它最终会给出一个NA)。是否有可能修改您的答案以适应这些条件?(我很抱歉没有提出更好的问题)。我将更新我的示例数据集以尝试包含这些内容。id 4的最后一行的输出是什么?就像noob一样,我没有指定年龄的编码(它是分类的,不是数字的)。我还将真实数据添加到了问题中。这并不重要,因为我们正在进行分组,并且值是根据numericHmmm计算的。我这方面一定很傻。我不想再浪费你的时间了,谢谢你的帮助!
# A tibble: 8 x 4
id age year var1
<int> <chr> <int> <dbl>
1 4 KL 2007 0
2 1 KL 2008 -0.707
3 2 KL 2008 0.707
4 4 AG 2008 NA
5 3 AG 2008 0
6 3 SU 2009 NA
7 4 SU 2009 NA
8 4 LL 2011 NA
df <- structure(list(id = c(4L, 1L, 2L, 4L, 3L, 3L, 4L, 4L), age = c("KL",
"KL", "KL", "AG", "AG", "SU", "SU", "LL"), year = c(2007L, 2008L,
2008L, 2008L, 2008L, 2009L, 2009L, 2011L), var1 = c(15L, 10L,
20L, NA, 5L, NA, NA, NA)), class = "data.frame", row.names = c(NA,
-8L))