R 将因子转换为新变量

R Converting Factors into New Variables

我有两个多层次的变量; V1 有 400 个级别,V2 有 ≈ 250 个级别。如何将 V2 的因子转换为多个不同的变量,并使用变量 V1 作为唯一标识符?

V1             V2
Garza, Mike    a
Garza, Mike    b
Smith, James   a 
Smith, James   f 
Smith, James   z 
Moore, Jen     b
Klein, April   f

数据框应如下例所示。注意:变量如何包含多个因素,而不是每个因素一个变量。考虑到 Mike 有两个因素与他相关,因素 a 和 b 进入 V2 和 V3,而 Jen,因素 b 也进入 V2,而不是 V3。

V1             V2 V3 V4 V5
Garza, Mike    a  b
Smith, James   a  f  z
Moore, Jen     b
Klein, April   f

如有任何帮助,我们将不胜感激!

谢谢。

这是一个整形问题。考虑 df 是你的 data.frame,你可以尝试使用这个:

> library(reshape2)
> print(dcast(melt(df), ...~V2), na.print="")
Using V1, V2 as id variables
Using V2 as value column: use value.var to override.
           V1 a b f z
1  Garza,Mike a b    
2 Klein,April     f  
3   Moore,Jen   b    
4 Smith,James a   f z

您似乎需要每个 V1 级别(个人)存在的 V2 级别的向量。这不是 真正 列在 data.frames 中的设计方式,即使您可以在 Excel 中做到这一点。相反,我建议您将结果作为每个人的向量,如下所示:

split(df$V2, df$V1)

哪个returns:

$`Garza, Mike`
[1] a b
Levels: a b f z

$`Klein, April`
[1] f
Levels: a b f z

$`Moore, Jen`
[1] b
Levels: a b f z

$`Smith, James`
[1] a f z
Levels: a b f z

在不知道你的用例的情况下,我不能说这是否真的会更好。但是,根据我的一般经验,它往往更容易使用。如果您只需要打印它们,您可以随时折叠它们。例如,如果将上面的 split 结果保存到 out,您可以这样做,然后可以将其作为列添加到其他输出 table:

out <- split(df$V2, df$V1)

sapply(out, paste, collapse = ", ")

给予

 Garza, Mike Klein, April   Moore, Jen Smith, James 
      "a, b"          "f"          "b"    "a, f, z" 

或者,如果你想知道谁拥有某个组,你可以这样做:

sapply(out, function(x){"f" %in% x})

给出:

 Garza, Mike Klein, April   Moore, Jen Smith, James 
       FALSE         TRUE        FALSE         TRUE 

您可以使用 reshape 包中的 dcast 完成第一部分,然后使用 apply.

将它们进一步排序到您想要的输出
dat <- data.frame(V1 = factor(c("Garza", "Garza",
                          "Smith", "Smith", "Smith",
                          "Moore", "Klein")),
                  V2 = c("a","b","a","f","z","b","f"))

# recast your data
dd <- dcast(dat, V1~V2)

#make a function to use with apply

shift_values<- function(x){
  notna <-which(!is.na(x[-1]))
  val <- x[notna+1]
  x[-1] <- c(as.character(val), rep("", (length(x)-1-length(val))))
  return(x)
}

# use it in an apply loop, transpose the data, and turn it into a data.frame
result <- data.frame(t(apply(dd, 1, shift_values)))

# change the column names
colnames(result)[-1] <- paste0("V", 2:(ncol(result)))

数据看起来像这样:

     V1 V2 V3 V4 V5
1 Garza  a  b      
2 Klein  f         
3 Moore  b         
4 Smith  a  f  z