R - 将data.frame中的值/因子分配给以其他列的值为条件的列

时间:2014-08-13 13:16:20

标签: r dataframe conditional assign

set.seed(8)
df <- data.frame(n = rnorm(5,1), m = rnorm(5,0), l = factor(LETTERS[1:5]))

我是否可以在df中以n,m和l的值或值组合为基础创建新列。 例如,根据levellow的值(伪代码)制作向量medium并为其分配highnm ):

df$level <- ifelse(df$n < 1 & df$m < 1, "low", ifelse(df$n > 1 & df$m > 1, "high", "medium")

这应该给出:

df$level

#low medium low low medium 

或者,如果我想根据level列和l中的值(再次为伪代码)为n分配值:

df$level <- ifelse(df$n < 1 & df$l == c("A", "B"), "low A/B", "high").

在这种情况下,应该得到:

df$level

#"low A/B" "high" "high" "high" "high"

4 个答案:

答案 0 :(得分:3)

这是一个解决方案:

df$level1 <- c("low", "medium", "high")[rowMeans(sign(df[c("n", "m")] - 1)) + 2]

df$level2 <- c("high", "low A/B")[(df$n < 1 & df$l %in% c("A", "B")) + 1]

#           n          m l level1  level2
# 1 0.9154139 -0.1078814 A    low low A/B
# 2 1.8404001 -0.1702891 B medium    high
# 3 0.5365172 -1.0883317 C    low    high
# 4 0.4491650 -3.0110517 D    low    high
# 5 1.7360404 -0.5931743 E medium    high

答案 1 :(得分:2)

你也可以这样做:

 c("high", "medium", "low")[rowSums(df[,-3] <1)+1]
#[1] "low"    "medium" "low"    "low"    "medium"

c("high", "low A/B")[(df$n <1 &grepl("A|B", df$l)) +1]
#[1] "low A/B" "high"    "high"    "high"    "high"   

解释

  • df[,-3]获取数字列的子集,即nm
  • 如果元素为df[,-3] <1
  • TRUE会给出FALSE<1的逻辑索引。
  • 通过对上面的rowSums进行操作,它根据每行中的对应值是否> 1,一个值<1,并给出三个可能的值 - 0,1,2,以及两者都<1。

    rowSums(df[,-3] <1) #in this example, there are no values equal to 0
    #[1] 2 1 2 2 1
    
  • 上面的
  • +1会给我们

    rowSums(df[,-3] <1) +1
    #[1] 3 2 3 3 2
    
  • 使用上面的数字索引,我们可以这样做:

      c("high", "medium", "low")[rowSums(df[,-3] <1)+1]
      #[1] "low"    "medium" "low"    "low"    "medium"
    
  • low将占用3上数字值medium2的地方,如果有1,则high应占据该地点。

答案 2 :(得分:1)

我可能错过了这个问题,但是当我添加缺少右括号时,它似乎工作得很好:

> df$level <- ifelse(df$n < 1 & df$m < 1, "low", ifelse(df$n > 1 & df$m > 1, "high", "medium"))
> df
          n          m l  level
1 0.9154139 -0.1078814 A    low
2 1.8404001 -0.1702891 B medium
3 0.5365172 -1.0883317 C    low
4 0.4491650 -3.0110517 D    low
5 1.7360404 -0.5931743 E medium
> df$level
[1] "low"    "medium" "low"    "low"    "medium"

答案 3 :(得分:0)

更多的扩展评论而不是答案,也许并不完全是您正在寻找的内容。

通常,当我需要捕获连续变量组并将它们转换为单个分类变量时,我会使用聚类并根据显示的值标记聚类。这是使用kmeans的一个例子:

set.seed(8)
df <- data.frame(n = rnorm(5000,1), m = rnorm(5000,0), l = factor(LETTERS[1:5]))
df$Category <- kmeans(df[1:2],7)$cluster

kmeans(df[1:2],7)
K-means clustering with 7 clusters of sizes 593, 606, 649, 626, 641, 1219, 666

Cluster means:
           n           m
1 -0.2097451  0.84837728 # Low-High
2  1.0977826  1.44383531 # Mid-Upper
3  2.1682482 -0.70983193 # High-Low
4 -0.3389432 -0.54514302 # Low-Low
5  2.3332772  0.67415808 # High-Mid
6  0.9816709 -0.01549909 # Upper-Mid
7  0.8859904 -1.46126667 # Mid-Low

df$Category <- factor(df$Category, c("Low-High","Mid-Upper","High-Low","Low-Low",...))

您必须查看自己计算机上群集的平均结果(使用种子)才能正确标记它们。这也将为您提供基于您的数据的分组,而不是您认为对数据正确的任意阈值。