我有一个包含员工ID和直属经理ID的员工信息列表。我想重新整理数据,这样它将列出每位员工的所有级别的经理。
我想创建一个循环以反复查找生产线经理。
这是创建示例数据集的代码。
LPC_PINCON
这是我期望的: 以employee_id 4为例
PINSEL1
我还应该提到,这是一个简化的示例。在我正在使用的真实数据中,经理和员工ID是不连续的。它们是一些带有前缀的随机数。 ID本身在管理级别上没有任何信息。级别完全由数据驱动。
答案 0 :(得分:2)
似乎需要迭代解决方案。
从我们员工的1级经理开始。每个雇员的经理的雇员的行索引是
i <- 1
idx = match(hr$manager_id, hr$employee_id)
经理的经理是hr$manager_id[idx]
,我们可以迭代地使用相同的match()
方法。记录并重复,直到只有一名员工担任经理
repeat {
idx = match(hr$manager_id[idx], hr$employee_id)
hr[[paste0("manager_", i)]] = hr$employee_id[idx]
if (length(unique(idx)) == 1)
break
i <- i + 1
}
通过使用NA
作为经理并适当地停止工作,变体可以允许一个或多个高层经理
hr$employee_id[1] = NA # the boss; there could be several top-level managers...
i <- 1
idx = match(hr$manager_id, hr$employee_id)
repeat {
idx = match(hr$manager_id[idx], hr$employee_id)
hr[[paste0("manager_", i)]] = hr$employee_id[idx]
if (all(is.na(idx)))
break
i <- i + 1
}
答案 1 :(得分:1)
这里是define ('WP_ALLOW_MULTISITE', true);
import React, { Fragment, useState, useEffect } from 'react';
import { Form, Button, Popover, OverlayTrigger } from 'react-bootstrap';
const Filter = props => {
const [formData, setFormData] = useState({
filter: ''
});
const [items, setItems] = useState([]);
const [retrievedItems, setRetrievedItems] = useState([]);
const addToFilter = newFilter => {
let retrievedFilter = ["da vinci","paris", "london"];
console.log(retrievedFilter);
if (retrievedFilter.length > 0) {
setRetrievedItems([...retrievedItems, retrievedFilter]);
retrievedFilter = 0;
setRetrievedItems([...retrievedItems, newFilter]);
} else {
setItems([...items, newFilter]);
}
console.log('items are: ', items);
console.log('retrieve filter', props.retrievedFilter);
console.log('retrieved items: ', retrievedItems);
};
useEffect(() => {
console.log('useEffect ', retrievedItems);
}, [retrievedItems]);
const deleteFilter = index => {
// props.retrievedFilter.splice(index, 1);
items.splice(index, 1);
setItems([...items]);
// setItems([...props.retrievedFilter, ...items]);
console.log(items);
};
const { filter } = formData;
const onChange = e => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
const onSubmit = e => {
e.preventDefault();
addToFilter(filter);
// Passing filter data up (i.e: to components that use <Filter />)
props.filterData(filter);
//Close the Popover
document.body.click();
};
const popover = (
<Popover id="popover-basic">
<Form>
<Form.Group controlId="formGroupEmail">
<Form.Label>Add New Filter</Form.Label>
<Form.Control
type="text"
placeholder="New Filter"
name="filter"
onChange={e => onChange(e)}
/>
</Form.Group>
<Button variant="dark" type="submit" onClick={e => onSubmit(e)}>
Add
</Button>
</Form>
</Popover>
);
return (
<Fragment>
<label>
<p className="filter-title">{props.title}</p>
</label>
<div className={props.className ? props.className : 'filter'}>
{!props.retrievedFilter
? items.map((item, index) => {
return (
<div className="filter-text" key={index}>
{item}
<Button
className="filter-button"
size="sm"
onClick={() => deleteFilter(index)}
>
X
</Button>
</div>
);
})
: props.retrievedFilter.map((item, index) => {
return (
<div className="filter-text" key={index}>
{item}
<Button
className="filter-button"
size="sm"
onClick={() => deleteFilter(index)}
>
X
</Button>
</div>
);
})}
<OverlayTrigger
trigger="click"
placement="right"
rootClose
overlay={popover}
>
<p className="text-field">Type new one</p>
</OverlayTrigger>
</div>
</Fragment>
);
};
export default Filter;
或者使用tidyverse
和library(tidyverse)
hr %>%
uncount(manager_id, .remove = FALSE) %>%
group_by(employee_id) %>%
mutate(new_id = row_number(), nm1 = str_c('manager_', new_id)) %>%
spread(nm1,new_id)
# A tibble: 10 x 7
# Groups: employee_id [10]
# employee_id manager_id manager_1 manager_2 manager_3 manager_4 manager_5
# <int> <dbl> <int> <int> <int> <int> <int>
# 1 1 1 1 NA NA NA NA
# 2 2 1 1 NA NA NA NA
# 3 3 2 1 2 NA NA NA
# 4 4 3 1 2 3 NA NA
# 5 5 4 1 2 3 4 NA
# 6 6 2 1 2 NA NA NA
# 7 7 3 1 2 3 NA NA
# 8 8 1 1 NA NA NA NA
# 9 9 4 1 2 3 4 NA
#10 10 5 1 2 3 4 5
map