在R中的dataframe列上定义函数时出错

在R中的dataframe列上定义函数时出错,r,dataframe,dplyr,pca,categorical-data,R,Dataframe,Dplyr,Pca,Categorical Data,我有一个数据框架,称之为a,其中列是问题1、问题2、问题3等等,行由回答问题的人、人1、人2等索引。这些问题有多种选择答案,长度不一。例如,问题50可能有9个可能的答案(每个人只能选择一个答案)。例如,问题50栏中的条目是从1到9的数字 为了对这个数据集进行PCA,我需要将这些列转换为二进制形式。例如,问题50列将被转换成9个不同的列:Q501、Q502、Q503……Q509。然后,如果K对问题50回答i,则Q50i,K行,将为1,否则为0。换句话说,我将我的列作为指示向量,由哪个人给出响应 我

我有一个数据框架,称之为a,其中列是问题1、问题2、问题3等等,行由回答问题的人、人1、人2等索引。这些问题有多种选择答案,长度不一。例如,问题50可能有9个可能的答案(每个人只能选择一个答案)。例如,问题50栏中的条目是从1到9的数字

为了对这个数据集进行PCA,我需要将这些列转换为二进制形式。例如,问题50列将被转换成9个不同的列:Q501、Q502、Q503……Q509。然后,如果K对问题50回答i,则Q50i,K行,将为1,否则为0。换句话说,我将我的列作为指示向量,由哪个人给出响应

我想写一个函数,将一列作为输入,并对我的数据集进行二进制编码。我可以对特定的一列执行此操作,但是当我尝试将相同的语法转换为一个函数(以便我可以将该函数应用于一系列列)时,R似乎无法计算我的变量。因为我有122列要转换,所以确实需要一个函数

以下是对特定列(本例中为50)起作用的内容:

以下是一个例子:

A是以下数据帧

   ID Q050
1   1    4
2   2    4
3   3    4
4   4    7
5   5    8
6   6    8
7   7    7
8   8    4
9   9    7
10 10    7
现在,我应用有效的方法:

for (i in 1:max(A["Q050"])) {
  A[paste0("Q050",i)] <- ifelse( A["Q050"]==i,1,0)
}
这很好,但是如果我将我以前的函数二值化,我只会得到与上面提到的相同的错误

我的问题是,我的函数binarize有什么问题。这对我来说是最好的方式吗?谢谢大家!

您可以尝试(对于使用
base R
的多列)

set.seed(45)

dat1“重塑2”软件包的“dcast”功能在这里可能有用:

> dd = data.frame(ID=letters[1:10], Q050=sample(1:10, 10))
> dd
   ID Q050
1   a    5
2   b    2
3   c    9
4   d    8
5   e    1
6   f    7
7   g    4
8   h    3
9   i   10
10  j    6
> 
> library(reshape2)
> dcast(dd, ID~Q050)
Using Q050 as value column: use value.var to override.
   ID  1  2  3  4  5  6  7  8  9 10
1   a NA NA NA NA  5 NA NA NA NA NA
2   b NA  2 NA NA NA NA NA NA NA NA
3   c NA NA NA NA NA NA NA NA  9 NA
4   d NA NA NA NA NA NA NA  8 NA NA
5   e  1 NA NA NA NA NA NA NA NA NA
6   f NA NA NA NA NA NA  7 NA NA NA
7   g NA NA NA  4 NA NA NA NA NA NA
8   h NA NA  3 NA NA NA NA NA NA NA
9   i NA NA NA NA NA NA NA NA NA 10
10  j NA NA NA NA NA  6 NA NA NA NA
> 
将二进制的所有正值转换为1:

> outdf[outdf>0]=1
Warning message:
In Ops.factor(left, right) : > not meaningful for factors
> outdf
   ID  1  2  3  4  5  6  7  8  9 10
1   a NA NA NA NA  1 NA NA NA NA NA
2   b NA  1 NA NA NA NA NA NA NA NA
3   c NA NA NA NA NA NA NA NA  1 NA
4   d NA NA NA NA NA NA NA  1 NA NA
5   e  1 NA NA NA NA NA NA NA NA NA
6   f NA NA NA NA NA NA  1 NA NA NA
7   g NA NA NA  1 NA NA NA NA NA NA
8   h NA NA  1 NA NA NA NA NA NA NA
9   i NA NA NA NA NA NA NA NA NA  1
10  j NA NA NA NA NA  1 NA NA NA NA
如果需要,将所有NA转换为0:

> outdf[is.na(outdf)]=0
> outdf
   ID 1 2 3 4 5 6 7 8 9 10
1   a 0 0 0 0 1 0 0 0 0  0
2   b 0 1 0 0 0 0 0 0 0  0
3   c 0 0 0 0 0 0 0 0 1  0
4   d 0 0 0 0 0 0 0 1 0  0
5   e 1 0 0 0 0 0 0 0 0  0
6   f 0 0 0 0 0 0 1 0 0  0
7   g 0 0 0 1 0 0 0 0 0  0
8   h 0 0 1 0 0 0 0 0 0  0
9   i 0 0 0 0 0 0 0 0 0  1
10  j 0 0 0 0 0 1 0 0 0  0
对于多列:

> dd = data.frame(ID=letters[1:15], Q050=sample(1:10, 15, replace=T), Q010=sample(1:10, 15, replace=T), Q020=sample(1:10, 15, replace=T))
使用重塑2的“熔化”获得长形:

> library(reshape2)
> mm = melt(dd, id='ID')
> head(mm)
  ID variable value
1  a     Q050     2
2  b     Q050     2
3  c     Q050     8
4  d     Q050     1
5  e     Q050     3
6  f     Q050     4
将此长表单拆分为带有不同问题的数据框:

> ll =split(mm, mm$variable)
> ll
$Q050
   ID variable value
1   a     Q050     2
2   b     Q050     2
3   c     Q050     8
4   d     Q050     1
5   e     Q050     3
6   f     Q050     4
7   g     Q050     8
8   h     Q050     5
9   i     Q050     4
10  j     Q050     1
11  k     Q050     5
12  l     Q050     4
13  m     Q050    10
14  n     Q050     2
15  o     Q050     2

$Q010
   ID variable value
16  a     Q010    10
17  b     Q010     6
18  c     Q010     6
19  d     Q010     6
20  e     Q010     2
21  f     Q010     2
22  g     Q010     6
23  h     Q010     4
24  i     Q010    10
25  j     Q010     4
26  k     Q010     9
27  l     Q010     8
28  m     Q010     7
29  n     Q010    10
30  o     Q010     6

$Q020
   ID variable value
31  a     Q020     7
32  b     Q020     7
33  c     Q020     9
34  d     Q020    10
35  e     Q020     6
36  f     Q020     6
37  g     Q020     2
38  h     Q020     4
39  i     Q020     7
40  j     Q020     1
41  k     Q020     4
42  l     Q020     4
43  m     Q020     5
44  n     Q020     8
45  o     Q020     5
使用“sapply”功能对每个数据帧/问题执行“dcast”:

sapply(ll, function(x) dcast(x, ID~value))

> sapply(ll, function(x) dcast(x, ID~value))
$Q050
   ID  1  2  3  4  5  8 10
1   a NA  2 NA NA NA NA NA
2   b NA  2 NA NA NA NA NA
3   c NA NA NA NA NA  8 NA
4   d  1 NA NA NA NA NA NA
5   e NA NA  3 NA NA NA NA
6   f NA NA NA  4 NA NA NA
7   g NA NA NA NA NA  8 NA
8   h NA NA NA NA  5 NA NA
9   i NA NA NA  4 NA NA NA
10  j  1 NA NA NA NA NA NA
11  k NA NA NA NA  5 NA NA
12  l NA NA NA  4 NA NA NA
13  m NA NA NA NA NA NA 10
14  n NA  2 NA NA NA NA NA
15  o NA  2 NA NA NA NA NA

$Q010
   ID  2  4  6  7  8  9 10
1   a NA NA NA NA NA NA 10
2   b NA NA  6 NA NA NA NA
3   c NA NA  6 NA NA NA NA
4   d NA NA  6 NA NA NA NA
5   e  2 NA NA NA NA NA NA
6   f  2 NA NA NA NA NA NA
7   g NA NA  6 NA NA NA NA
8   h NA  4 NA NA NA NA NA
9   i NA NA NA NA NA NA 10
10  j NA  4 NA NA NA NA NA
11  k NA NA NA NA NA  9 NA
12  l NA NA NA NA  8 NA NA
13  m NA NA NA  7 NA NA NA
14  n NA NA NA NA NA NA 10
15  o NA NA  6 NA NA NA NA

$Q020
   ID  1  2  4  5  6  7  8  9 10
1   a NA NA NA NA NA  7 NA NA NA
2   b NA NA NA NA NA  7 NA NA NA
3   c NA NA NA NA NA NA NA  9 NA
4   d NA NA NA NA NA NA NA NA 10
5   e NA NA NA NA  6 NA NA NA NA
6   f NA NA NA NA  6 NA NA NA NA
7   g NA  2 NA NA NA NA NA NA NA
8   h NA NA  4 NA NA NA NA NA NA
9   i NA NA NA NA NA  7 NA NA NA
10  j  1 NA NA NA NA NA NA NA NA
11  k NA NA  4 NA NA NA NA NA NA
12  l NA NA  4 NA NA NA NA NA NA
13  m NA NA NA  5 NA NA NA NA NA
14  n NA NA NA NA NA NA  8 NA NA
15  o NA NA NA  5 NA NA NA NA NA

对每个步骤进行解释,并使用参数避免调用额外的方法

1) 使用grep从df中开始的列名中获取所有项目,因此使用“^”和Q.
我们传递参数value=TRUE,以便获得准确的列名,而不是它们的索引

   questions.labels <- grep("^Q", colnames(df), value=TRUE)

questions.label会让你遇到问题。添加一些示例输入和所需输出。你肯定在
max(A[“column]”)
方面有问题,我想你的意思是
max(A[[column]”)
,但是如果没有测试数据,就很难验证。请参阅
?model.matrix
谢谢!还有一个问题,我想在最后有一个数据帧,包含所有这些列,而不是连接所有的lst条目,有没有一种方法可以使用原始函数实现这一点?谢谢!如何一次对多个列执行此操作,并最终获得一个数据帧。我需要这样做大约100列。
> outdf[is.na(outdf)]=0
> outdf
   ID 1 2 3 4 5 6 7 8 9 10
1   a 0 0 0 0 1 0 0 0 0  0
2   b 0 1 0 0 0 0 0 0 0  0
3   c 0 0 0 0 0 0 0 0 1  0
4   d 0 0 0 0 0 0 0 1 0  0
5   e 1 0 0 0 0 0 0 0 0  0
6   f 0 0 0 0 0 0 1 0 0  0
7   g 0 0 0 1 0 0 0 0 0  0
8   h 0 0 1 0 0 0 0 0 0  0
9   i 0 0 0 0 0 0 0 0 0  1
10  j 0 0 0 0 0 1 0 0 0  0
> dd = data.frame(ID=letters[1:15], Q050=sample(1:10, 15, replace=T), Q010=sample(1:10, 15, replace=T), Q020=sample(1:10, 15, replace=T))
> library(reshape2)
> mm = melt(dd, id='ID')
> head(mm)
  ID variable value
1  a     Q050     2
2  b     Q050     2
3  c     Q050     8
4  d     Q050     1
5  e     Q050     3
6  f     Q050     4
> ll =split(mm, mm$variable)
> ll
$Q050
   ID variable value
1   a     Q050     2
2   b     Q050     2
3   c     Q050     8
4   d     Q050     1
5   e     Q050     3
6   f     Q050     4
7   g     Q050     8
8   h     Q050     5
9   i     Q050     4
10  j     Q050     1
11  k     Q050     5
12  l     Q050     4
13  m     Q050    10
14  n     Q050     2
15  o     Q050     2

$Q010
   ID variable value
16  a     Q010    10
17  b     Q010     6
18  c     Q010     6
19  d     Q010     6
20  e     Q010     2
21  f     Q010     2
22  g     Q010     6
23  h     Q010     4
24  i     Q010    10
25  j     Q010     4
26  k     Q010     9
27  l     Q010     8
28  m     Q010     7
29  n     Q010    10
30  o     Q010     6

$Q020
   ID variable value
31  a     Q020     7
32  b     Q020     7
33  c     Q020     9
34  d     Q020    10
35  e     Q020     6
36  f     Q020     6
37  g     Q020     2
38  h     Q020     4
39  i     Q020     7
40  j     Q020     1
41  k     Q020     4
42  l     Q020     4
43  m     Q020     5
44  n     Q020     8
45  o     Q020     5
sapply(ll, function(x) dcast(x, ID~value))

> sapply(ll, function(x) dcast(x, ID~value))
$Q050
   ID  1  2  3  4  5  8 10
1   a NA  2 NA NA NA NA NA
2   b NA  2 NA NA NA NA NA
3   c NA NA NA NA NA  8 NA
4   d  1 NA NA NA NA NA NA
5   e NA NA  3 NA NA NA NA
6   f NA NA NA  4 NA NA NA
7   g NA NA NA NA NA  8 NA
8   h NA NA NA NA  5 NA NA
9   i NA NA NA  4 NA NA NA
10  j  1 NA NA NA NA NA NA
11  k NA NA NA NA  5 NA NA
12  l NA NA NA  4 NA NA NA
13  m NA NA NA NA NA NA 10
14  n NA  2 NA NA NA NA NA
15  o NA  2 NA NA NA NA NA

$Q010
   ID  2  4  6  7  8  9 10
1   a NA NA NA NA NA NA 10
2   b NA NA  6 NA NA NA NA
3   c NA NA  6 NA NA NA NA
4   d NA NA  6 NA NA NA NA
5   e  2 NA NA NA NA NA NA
6   f  2 NA NA NA NA NA NA
7   g NA NA  6 NA NA NA NA
8   h NA  4 NA NA NA NA NA
9   i NA NA NA NA NA NA 10
10  j NA  4 NA NA NA NA NA
11  k NA NA NA NA NA  9 NA
12  l NA NA NA NA  8 NA NA
13  m NA NA NA  7 NA NA NA
14  n NA NA NA NA NA NA 10
15  o NA NA  6 NA NA NA NA

$Q020
   ID  1  2  4  5  6  7  8  9 10
1   a NA NA NA NA NA  7 NA NA NA
2   b NA NA NA NA NA  7 NA NA NA
3   c NA NA NA NA NA NA NA  9 NA
4   d NA NA NA NA NA NA NA NA 10
5   e NA NA NA NA  6 NA NA NA NA
6   f NA NA NA NA  6 NA NA NA NA
7   g NA  2 NA NA NA NA NA NA NA
8   h NA NA  4 NA NA NA NA NA NA
9   i NA NA NA NA NA  7 NA NA NA
10  j  1 NA NA NA NA NA NA NA NA
11  k NA NA  4 NA NA NA NA NA NA
12  l NA NA  4 NA NA NA NA NA NA
13  m NA NA NA  5 NA NA NA NA NA
14  n NA NA NA NA NA NA  8 NA NA
15  o NA NA NA  5 NA NA NA NA NA
   questions.labels <- grep("^Q", colnames(df), value=TRUE)
library("reshape2")
    df.melt <- melt(df, 
                    id='ID', 
                    measure.vars=questions.labels)
    df.split <- split(df.melt, df.melt$variable)
    df.bin <- sapply(df.split, function(x) dcast(x, ID~value, function(x) 1, fill=0))