在 R 的面板数据集中组合变量的更好方法?
Better way to combine variables in panel dataset in R?
我正在处理面板数据,其中一些问卷项目只被问过一次,而大多数其他问卷项目在不同的波次中被问过多次。因此,让我们假设我有关于分类变量的调查回复。
尽管小组成员对给定问题的回答可能会很稳定,但他们也可能会改变意见,甚至退出小组。其他人可能会在稍后的时间点(在后面的波次中)进入小组。
所以假设这导致了一个看起来像这样的数据集,其中 var_1a 和 var_1b 是两个变量,它们仅在两个不同的波浪中测量相同的事物:
mydata<-data.frame(
var_1a = c(1,2,3,4,5,NA),
var_1b = c(1,2,5,5,NA,NA)
)
现在我想自动将这些变量组合成跨越两个波的一个变量。作为一个条件,如果受访者的意见从一波改变到另一波,我想取平均值。此外,即使受访者在第 2 波中退出小组,我也希望保留第 1 波的回复。
我在 R 中一直这样做的方法是使用这个函数:
combo<-function(x,...){
V<-rowMeans(x[, c(...) ], na.rm=T) *
ifelse(rowMeans(is.na(x[, c(...) ])) == ncol(x[, c(...) ]), NA, 1)
ifelse(is.nan(V),NA,V)}
出于某种原因,这会引入 "NaN" 如果所有变量在所有波中始终为 NA,因此函数中的最后一行代码。
这很好用,我得到了我想要的:
> mydata$combo_var<-combo(mydata, c("var_1a","var_1b"))
> mydata
var_1a var_1b combo_var
1 1 1 1.0
2 2 2 2.0
3 3 -3 0.0
4 4 9 6.5
5 5 NA 5.0
6 NA NA NA
7 NA NA NA
8 NA NA NA
9 NA NA NA
10 NA NA NA
不过,我想知道是否有更好、更简单的方法来做到这一点。有没有办法可以使用 dplyr 来做同样的事情?任何 tidyverse 解决方案?
您可以通过避免使用 ifelse
来更清楚地表达这一点。
combo2 <- function(dat, sset) {
r <- rowMeans(dat[sset], na.rm=TRUE)
r[is.nan(r)] <- NA
return(r)
}
mydata1$combo_var <- combo2(mydata1, c("var_1a", "var_1b"))
# var_1a var_1b combo_var
# 1 1 1 1.0
# 2 2 2 2.0
# 3 3 -3 0.0
# 4 4 9 6.5
# 5 5 NA 5.0
# 6 NA NA NA
# 7 NA NA NA
# 8 NA NA NA
# 9 NA NA NA
# 10 NA NA NA
数据
mydata1 <- structure(list(var_1a = c(1L, 2L, 3L, 4L, 5L, NA, NA, NA, NA,
NA), var_1b = c(1L, 2L, -3L, 9L, NA, NA, NA, NA, NA, NA)), row.names = c(NA,
-10L), class = "data.frame")
一些tidyverse
选项:
数据
mydata <- data.frame(
var_1a = c(1,2,3,4,5,NA),
var_1b = c(1,2,5,5,NA,NA)
)
选项 1
library(dplyr)
library(purrr)
mydata <- mydata %>%
mutate(
combo_var = pmap_dbl(select(., contains("var")),
~mean(c(...), na.rm = T))
)
结果:
var_1a var_1b combo_var
1 1 1 1.0
2 2 2 2.0
3 3 5 4.0
4 4 5 4.5
5 5 NA 5.0
6 NA NA NaN
选项 2
mydata <- mydata %>%
mutate(
combo_var = rowMeans(select(., contains("var")), na.rm = T)
)
结果:
var_1a var_1b combo_var
1 1 1 1.0
2 2 2 2.0
3 3 5 4.0
4 4 5 4.5
5 5 NA 5.0
6 NA NA NaN
我正在处理面板数据,其中一些问卷项目只被问过一次,而大多数其他问卷项目在不同的波次中被问过多次。因此,让我们假设我有关于分类变量的调查回复。
尽管小组成员对给定问题的回答可能会很稳定,但他们也可能会改变意见,甚至退出小组。其他人可能会在稍后的时间点(在后面的波次中)进入小组。
所以假设这导致了一个看起来像这样的数据集,其中 var_1a 和 var_1b 是两个变量,它们仅在两个不同的波浪中测量相同的事物:
mydata<-data.frame(
var_1a = c(1,2,3,4,5,NA),
var_1b = c(1,2,5,5,NA,NA)
)
现在我想自动将这些变量组合成跨越两个波的一个变量。作为一个条件,如果受访者的意见从一波改变到另一波,我想取平均值。此外,即使受访者在第 2 波中退出小组,我也希望保留第 1 波的回复。
我在 R 中一直这样做的方法是使用这个函数:
combo<-function(x,...){
V<-rowMeans(x[, c(...) ], na.rm=T) *
ifelse(rowMeans(is.na(x[, c(...) ])) == ncol(x[, c(...) ]), NA, 1)
ifelse(is.nan(V),NA,V)}
出于某种原因,这会引入 "NaN" 如果所有变量在所有波中始终为 NA,因此函数中的最后一行代码。
这很好用,我得到了我想要的:
> mydata$combo_var<-combo(mydata, c("var_1a","var_1b"))
> mydata
var_1a var_1b combo_var
1 1 1 1.0
2 2 2 2.0
3 3 -3 0.0
4 4 9 6.5
5 5 NA 5.0
6 NA NA NA
7 NA NA NA
8 NA NA NA
9 NA NA NA
10 NA NA NA
不过,我想知道是否有更好、更简单的方法来做到这一点。有没有办法可以使用 dplyr 来做同样的事情?任何 tidyverse 解决方案?
您可以通过避免使用 ifelse
来更清楚地表达这一点。
combo2 <- function(dat, sset) {
r <- rowMeans(dat[sset], na.rm=TRUE)
r[is.nan(r)] <- NA
return(r)
}
mydata1$combo_var <- combo2(mydata1, c("var_1a", "var_1b"))
# var_1a var_1b combo_var
# 1 1 1 1.0
# 2 2 2 2.0
# 3 3 -3 0.0
# 4 4 9 6.5
# 5 5 NA 5.0
# 6 NA NA NA
# 7 NA NA NA
# 8 NA NA NA
# 9 NA NA NA
# 10 NA NA NA
数据
mydata1 <- structure(list(var_1a = c(1L, 2L, 3L, 4L, 5L, NA, NA, NA, NA,
NA), var_1b = c(1L, 2L, -3L, 9L, NA, NA, NA, NA, NA, NA)), row.names = c(NA,
-10L), class = "data.frame")
一些tidyverse
选项:
数据
mydata <- data.frame(
var_1a = c(1,2,3,4,5,NA),
var_1b = c(1,2,5,5,NA,NA)
)
选项 1
library(dplyr)
library(purrr)
mydata <- mydata %>%
mutate(
combo_var = pmap_dbl(select(., contains("var")),
~mean(c(...), na.rm = T))
)
结果:
var_1a var_1b combo_var
1 1 1 1.0
2 2 2 2.0
3 3 5 4.0
4 4 5 4.5
5 5 NA 5.0
6 NA NA NaN
选项 2
mydata <- mydata %>%
mutate(
combo_var = rowMeans(select(., contains("var")), na.rm = T)
)
结果:
var_1a var_1b combo_var
1 1 1 1.0
2 2 2 2.0
3 3 5 4.0
4 4 5 4.5
5 5 NA 5.0
6 NA NA NaN