使用R中的函数迭代包含不同长度的列号列表的数据框

时间:2019-02-07 19:33:24

标签: r

我有一个关于人类价值的调查响应的数据框(df),其中包含57列数字/比例响应的变量/变量。每个列都属于十个类别之一,它们不在连续的组中。

我有第二个数据框(记分表),将类别与变量的列号相关联;列号列表的长度都不同:

scoretable <- data.frame(
     valuename = 
     c("Conformity","Tradition","Benevolence","Universalism","Self- 
     Direction","Stimulation","Hedonism","Achievement","Power","Security"),
     valuevars = I(list(c(11,20,40,47), # Conformity
                        c(18,32,36,44,51), # Tradition
                        c(33,45,49,52,54), # Benevolence
                        c(1,17,24,26,29,30,35,38), # Universalism
                        c(5,16,31,41,53), # Self-Direction
                        c(9,25,37), # Stimulation
                        c(4,50,57), # Hedonism
                        c(34,39,43,55), # Achievement
                        c(3,12,27,46), # Power
                        c(8,13,15,22,56))), # Security
     stringsAsFactors=FALSE)

我想用一个名为valuescore的函数遍历记分表,该函数计算数据帧df中该列组中所有响应的均值和sd并将结果写入第三个结果表:

valuescore = function(df,scoretable,valueresults){
    valuename = scoretable[,1]
    set <- df[,scoretable[,2]]
    setmeans <- colMeans(set,na.rm=TRUE)
    valuemean <- mean(setmeans)
    setvars <- apply(set, 2, var)
    valuesd <-sqrt(mean(setvars))
    rbind(valueresults,c(valuename, valuemean, valuesd))
}

a <- nrow(scoretable)
for(i in 1:a){
    valuescore(df,scoretable[i,],valueresults)
}

我一般对R和编程都是陌生的(这是我的第一个问题),我正在努力确定如何将列表变量传递给函数和/或作为数据帧的地址范围。

2 个答案:

答案 0 :(得分:1)

让我们创建一个示例data.frame:

df <- replicate(57, rnorm(10, 50, 20)) %>% as.data.frame()

让我们准备表格结果格式:

valueresults <- data.frame(
  name = scoretable$valuename, 
  mean = 0
)

现在,对计分表的值进行循环,按列计算平均值,然后计算平均值。这很残酷(使用Map的第一个答案更优雅),但对于R初学者来说,也许更容易理解。

for(v in 1:nrow(scoretable)){
  # let's suppose v = 1 "Conformity"
  columns_id <- scoretable$valuevars[[v]]

  # isolate columns that correspond to 'Conformity'
  temp_df    <- df[, columns_id]

  # mean of the values of these columns
  temp_means <- apply(temp_df, 2, mean)
  mean       <- mean(temp_means)

  # save result in the prepared table
  valueresults$mean[v] <- mean
}

> (valueresults)
             name     mean
1      Conformity 45.75407
2       Tradition 52.76935
3     Benevolence 50.81724
4    Universalism 51.04970
5  Self-Direction 55.43723
6     Stimulation 52.15962
7        Hedonism 53.17395
8     Achievement 47.77570
9           Power 52.61731
10       Security 54.07066

答案 1 :(得分:0)

这是使用Map将函数应用于列表scoretable[, 2]的一种方法。

首先,我将创建一个测试df

set.seed(1234)
m <- 100
n <- 57
df <- matrix(sample(10, m*n, TRUE), nrow = m, ncol = n)
df <- as.data.frame(df)

现在是函数valuescore

valuescore <- function(DF, scores){
  f <- function(inx) mean(as.matrix(DF[, inx]), na.rm = TRUE)
  res <- Map(f, scores[, 2])
  names(res) <- scores[[1]]
  res
}

valuescore(df, scoretable)
#$Conformity
#[1] 5.5225
#
#$Tradition
#[1] 5.626
#
#$Benevolence
#[1] 5.548
#
#$Universalism
#[1] 5.36125
#
#$`Self-Direction`
#[1] 5.494
#
#$Stimulation
#[1] 5.643333
#
#$Hedonism
#[1] 5.546667
#
#$Achievement
#[1] 5.3175
#
#$Power
#[1] 5.41
#
#$Security
#[1] 5.54