R-比较具有不同值的数据框的不同列

R- compare different columns of a data frame with different values

我目前正在研究微数据,使用一项名为 SHARE 的调查。我想将变量用于教育,但它的编码方式有点困难。

在调查中,家庭被问及他们拥有什么学位。每个学位有一列,如果受访者是否有学位,则取值 0 或 1。问题是我有两个不同程度的国家,但他们使用的是同一列,所以我必须去用户手册找到每个国家对应的度数分别为 0 或 1。我能够这样做并且然后将其转化为衡量教育的国际方式。

我的想法是对每一列求和,然后每个家庭只有一列。但是,我无法继续,因为有些人有很多学位。我想获得每个家庭的最高学位。在这个问题上我想得到你的帮助。

以下是 table我拥有的和我想要的:

假设在德国,第一个文凭相当于国际标准的第一个文凭,德国的第二个和第三个文凭与国际标准的第二个文凭相同,德国的最后一个文凭与国际标准相同国际第三。在法国我们有 first = first int., second = second int., third = third int.没有第四个文凭。然后我有一个 table:

country= c( "Germany", "Germany", "Germany", "France" , "France", "France")
degree_one= c( 1, 1, 1, 1 , 1, 1)
degree_two = c( 0, 1, 0, 1 , 1, 0)
degree_three= c( 1, 0, 1, 1 , 1, 0)
degree_four = c( 1, 0, 0, NA ,NA,  NA)

f = data.frame(country,degree_one,degree_two,degree_three,degree_four)

然后我可以翻译并尝试通过对所有内容求和来创建我的变量度:

f$degree_one = ifelse(f$country == "Germany" & f$degree_one == 1,1,f$degree_one)
f$degree_two = ifelse(f$country == "Germany" & f$degree_two == 1,2,f$degree_two)
f$degree_three = ifelse(f$country == "Germany" & f$degree_three == 1,2,f$degree_three)
f$degree_four = ifelse(f$country == "Germany" & f$degree_four == 1,3,f$degree_four)

f$degree_one = ifelse(f$country == "France" & f$degree_one == 1,1,f$degree_one)
f$degree_two = ifelse(f$country == "France" & f$degree_two == 1,2,f$degree_two)
f$degree_three = ifelse(f$country == "France" & f$degree_three == 1,3,f$degree_three)
f$degree_four = ifelse(f$country == "France" & f$degree_four == "NA",0,f$degree_four)

f = replace(f, is.na(f), 0)

f2 = f %>% mutate(degree = degree_one + degree_two + degree_three + degree_four )

不幸的是,它不起作用,我想要的应该是这样的:

degree = c(3,2,2,3,3,1)
f3 = data.frame(f,degree)

我试着用 while 循环做 smth 但它没有用,因为有人知道我如何解决我的问题吗?我尽量把它说清楚了,我希望你能理解,并希望有人能提供解决此问题的想法。

谢谢:)

NAs 更改为 0,然后对度数列求和:

f <- f %>%
    mutate(
        degree_one = ifelse(is.na(degree_one), 0, degree_one),
        degree_two = ifelse(is.na(degree_two), 0, degree_two),
        degree_three = ifelse(is.na(degree_three), 0, degree_three),
        degree_four = ifelse(is.na(degree_four), 0, degree_four),
        degree_sum = degree_one + degree_two + degree_three + degree_four
)

或者,如果您想对 dplyr

感兴趣
f <- f %>% 
    mutate(across(contains("degree"), \(x) {ifelse(is.na(x), 0, x)})) %>% 
    mutate(degree_sum = select(., contains("degree")) %>% rowSums())

这是一种使用 data.table

的方法
library(data.table)
##
#  create degree map by country
#
degreeMap <- data.table(country=c('France', 'Germany'))
degreeMap <- degreeMap[, .(degree=paste('degree', c('one', 'two', 'three', 'four'), sep='_')), by=.(country)]
degreeMap[country=='France',  intlDegree:=c(1,2,3,NA)]
degreeMap[country=='Germany', intlDegree:=c(1,2,2,3)]
##
#   process your data
#
setDT(f)
f[, indx:=1:.N]                     # need an index column to recover original order
f[, HH:=1:.N, by=.(country)]        # need a  HH column to distinguish different HH w/in country
maxDegree <- melt(f, id=c('country', 'HH', 'indx'), variable.name='degree', value.name = 'flag')
maxDegree <- maxDegree[flag > 0]    # remove rows with flag=0 or NA
setorder(maxDegree, HH, degree)
maxDegree <- maxDegree[, .SD[.N], keyby=.(country, HH)]
maxDegree[degreeMap, intlDegree:=i.intlDegree, on=.(country, degree)]
setorder(maxDegree, indx)
maxDegree
##    country HH indx       degree flag intlDegree
## 1: Germany  1    1  degree_four    1          3
## 2: Germany  2    2   degree_two    1          2
## 3: Germany  3    3 degree_three    1          2
## 4:  France  1    4 degree_three    1          3
## 5:  France  2    5 degree_three    1          3
## 6:  France  3    6   degree_one    1          1

所以这会将您的 f 转换为 data.table 并添加一个索引列和一个 HH 列以区分一个国家/地区内的 HH。

然后我们使用 melt(...) 转换为长格式。在长格式中,四个 degree_ 列减少为两列:一个 flag 列表示该学位是否适用,一个 degree 列表示哪个学位。

然后我们删除所有带有 0 或 NA 标志的行,然后为每个国家和 HH 提取最后剩下的行(最高程度)。

最后,我们加入degreeMap以获得同等的国际学位。