根据第三列将列拆分为单独的列

时间:2017-03-21 13:31:06

标签: r

我的数据框出了问题。我想添加一个文章列,因为ItemType列是article_id&s;和payment_id' s的组合。

我已经编写了一些代码,因此您可以复制。

JLID <- c(1:9)
JLID <- as.data.frame(JLID)
JHID <- c(1, 1, 1, 1, 2, 2, 2, 3, 3)
JLID$JHID <- JHID
ItemType <- c("PLU", "PLU", "PAY", "PAY", "PLU", "PLU", "PAY", "PLU", "PAY")
JLID$ItemType <-ItemType
Itemiden <- c(37, 235, 1, 1, 35, 6, 1, 1, 1)
JLID$Itemiden <- Itemiden
quant <- c(3, 2, 1, 1, 1, 4, 1, 6, 1)
JLID$quant <-quant

如果您将其添加到代码中,您将获得我想要的数据。 基于ItemType是否为PLU。

Art <- c(37, 235, "", "", 35, 6, "", 1, "")
JLID$Art <- Art

拆分整个列Itemiden也是一个选项,但也必须基于ItemType,因为您可以看到某些Itemiden可能是付款或文章。

我的想法是这样的,因为我必须在大型数据集上执行此操作。

JLID [(JL$ItemType %in% "PLU"), "Art"] <- "JLID $Itemiden"

但它不起作用。

1 个答案:

答案 0 :(得分:1)

Q的标题可能会产生误导,因为split()是R中基函数的名称.OP希望向data.frame添加一列,该列填充第二列的值,具体取决于第三栏中的条件。

根据另一列

中的条件创建新列

在基础R中,我建议使用replace()函数

JLID$Art <- replace(JLID$Itemiden, JLID$ItemType != "PLU", "")

JLID
#  ID JHID ItemType Itemiden quant Art
#1  1    1      PLU       37     3  37
#2  2    1      PLU      235     2 235
#3  3    1      PAY        1     1    
#4  4    1      PAY        1     1    
#5  5    2      PLU       35     1  35
#6  6    2      PLU        6     4   6
#7  7    2      PAY        1     1    
#8  8    3      PLU        1     6   1
#9  9    3      PAY        1     1    

替代方案是分组

# copy whole column
JLID$Art <- JLID$Itemiden
# replace unwanted elements on condition
JLID$Art[JLID$ItemType != "PLU"] <- ""
{p {3>}

中建议的

ifelse()

JLID$Art <- ifelse(JLID$ItemType == "PLU", JLID$Itemiden, "")
# or
JLID$Art <- ifelse(JLID$ItemType != "PLU", "", JLID$Itemiden)

但请注意?ifelse的文件警告

  

结果的模式可能取决于test的值(参见示例),结果的类属性(请参阅oldClass)取自test并且可能不适合从yesno中选择的值。

ifelse()失败的地方

虽然在这种情况下ifelse()是一个可行的解决方案,但它并不总是与其他数据类型一样有效,例如DataPOSIXct。由于这个“feature”,我花了几个小时进行调试。一个例子:

JLID$PayDate <- ifelse(JLID$ItemType != "PLU", as.Date("2017-04-15"), NA)
JLID
#  ID JHID ItemType Itemiden quant Art PayDate
#1  1    1      PLU       37     3  37      NA
#2  2    1      PLU      235     2 235      NA
#3  3    1      PAY        1     1       17271
#4  4    1      PAY        1     1       17271
#5  5    2      PLU       35     1  35      NA
#6  6    2      PLU        6     4   6      NA
#7  7    2      PAY        1     1       17271
#8  8    3      PLU        1     6   1      NA
#9  9    3      PAY        1     1       17271

此处,该类已被剥离,日期显示为数字。

replace()或子集更可靠:

JLID$PayDate <- replace(rep(as.Date("2017-04-15"), nrow(JLID)), JLID$ItemType == "PLU", NA)
JLID
#  ID JHID ItemType Itemiden quant Art    PayDate
#1  1    1      PLU       37     3  37       <NA>
#2  2    1      PLU      235     2 235       <NA>
#3  3    1      PAY        1     1     2017-04-15
#4  4    1      PAY        1     1     2017-04-15
#5  5    2      PLU       35     1  35       <NA>
#6  6    2      PLU        6     4   6       <NA>
#7  7    2      PAY        1     1     2017-04-15
#8  8    3      PLU        1     6   1       <NA>
#9  9    3      PAY        1     1     2017-04-15

创建数据框

OP选择以可能导致问题的方式创建data.frame。也就是说,它包含一列JLID,它与data.frame本身具有相同的名称。这种模棱两可可能会导致意想不到的结果或错误(只是发生在我身上!)。

在基础R中,我建议手动设置数据框

JLID <- data.frame(
  ID = c(1:9),
  JHID = c(1, 1, 1, 1, 2, 2, 2, 3, 3),
  ItemType = c("PLU", "PLU", "PAY", "PAY", "PLU", "PLU", "PAY", "PLU", "PAY"),
  Itemiden = c(37, 235, 1, 1, 35, 6, 1, 1, 1),
  quant = c(3, 2, 1, 1, 1, 4, 1, 6, 1),
  stringsAsFactors = FALSE
)

str(JLID)
#'data.frame':  9 obs. of  5 variables:
# $ ID      : int  1 2 3 4 5 6 7 8 9
# $ JHID    : num  1 1 1 1 2 2 2 3 3
# $ ItemType: chr  "PLU" "PLU" "PAY" "PAY" ...
# $ Itemiden: num  37 235 1 1 35 6 1 1 1
# $ quant   : num  3 2 1 1 1 4 1 6 1

或者,如果列因某种原因已经存在

ID <- c(1:9)
JHID <- c(1, 1, 1, 1, 2, 2, 2, 3, 3)JLID$JHID <- JHID
ItemType <- c("PLU", "PLU", "PAY", "PAY", "PLU", "PLU", "PAY", "PLU", "PAY")
Itemiden <- c(37, 235, 1, 1, 35, 6, 1, 1, 1)
quant <- c(3, 2, 1, 1, 1, 4, 1, 6, 1)
JLID <- data.frame(ID, JHID, ItemType, Itemiden, quant, stringsAsFactors = FALSE)

注意,data.frame()要求明确说明不得强制要求因素与OP的样本数据一致。